From e110e99f66a8f3873afe587048765cbad769e65c Mon Sep 17 00:00:00 2001 From: Jiarui Li Date: Tue, 7 Jul 2026 15:43:11 +0800 Subject: [PATCH] Initial DeepHealthExpo next-token codebase --- .gitignore | 37 + LICENSE | 28 + README.md | 60 + backbones.py | 328 +++ dataset.py | 674 ++++++ eval_data.py | 163 ++ evaluate_auc.py | 1423 ++++++++++++ evaluate_token_auc.py | 7 + event_date_utils.py | 104 + extra_info_types_all.txt | 268 +++ extra_info_types_assessment_only.txt | 68 + extra_info_types_exposure_only.txt | 203 ++ extra_info_types_none.txt | 3 + extra_info_types_smoking_alcohol_bmi.txt | 6 + field_ids_enriched.csv | 2564 ++++++++++++++++++++++ future_risk.py | 115 + labels.csv | 1256 +++++++++++ losses.py | 400 ++++ models.py | 481 ++++ prepare_data.py | 385 ++++ prepare_event_dates.py | 203 ++ readouts.py | 107 + requirements.txt | 5 + targets.py | 394 ++++ train_next_step.py | 667 ++++++ train_util.py | 329 +++ 26 files changed, 10278 insertions(+) create mode 100644 .gitignore create mode 100644 LICENSE create mode 100644 README.md create mode 100644 backbones.py create mode 100644 dataset.py create mode 100644 eval_data.py create mode 100644 evaluate_auc.py create mode 100644 evaluate_token_auc.py create mode 100644 event_date_utils.py create mode 100644 extra_info_types_all.txt create mode 100644 extra_info_types_assessment_only.txt create mode 100644 extra_info_types_exposure_only.txt create mode 100644 extra_info_types_none.txt create mode 100644 extra_info_types_smoking_alcohol_bmi.txt create mode 100644 field_ids_enriched.csv create mode 100644 future_risk.py create mode 100644 labels.csv create mode 100644 losses.py create mode 100644 models.py create mode 100644 prepare_data.py create mode 100644 prepare_event_dates.py create mode 100644 readouts.py create mode 100644 requirements.txt create mode 100644 targets.py create mode 100644 train_next_step.py create mode 100644 train_util.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..eb26e3a --- /dev/null +++ b/.gitignore @@ -0,0 +1,37 @@ +# Python +__pycache__/ +*.py[cod] +*.pyo +.pytest_cache/ +.mypy_cache/ +.ruff_cache/ + +# Environments +.venv/ +venv/ +env/ + +# Training outputs +runs/ +outputs/ +checkpoints/ +*.pt +*.pth + +# Large/local data +ukb_*_data.npy +ukb_event_data.npy +ukb_other_info.npy +ukb_data.csv +ukb_basic_info.csv +ukb_train_eid.csv +ukb_val_eid.csv +ukb_test_eid.csv +UKB_*.csv +cate_types.csv +*.parquet + +# OS/editor +.DS_Store +Thumbs.db +.vscode/ diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..eeeec40 --- /dev/null +++ b/LICENSE @@ -0,0 +1,28 @@ +BSD 3-Clause License + +Copyright (c) 2026, Jiarui Li + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT INCLUDING NEGLIGENCE OR OTHERWISE ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..113881e --- /dev/null +++ b/README.md @@ -0,0 +1,60 @@ +# DeepHealthExpo + +Next-token DeepHealth training code for disease-event sequence modeling with optional extra/exposure information. + +This repository is a clean code-only extraction from the main DeepHealth project. It keeps the next-token training path and reusable model/data utilities, while excluding large UKB data files, trained checkpoints, result folders, and all-future training entry points. + +## Included + +- `train_next_step.py`: next-token / UTS training entry point. +- `dataset.py`: next-step event sequence dataset with unified extra-info tokens. +- `models.py`, `backbones.py`: DeepHealth Transformer backbone. +- `losses.py`, `readouts.py`, `targets.py`: training targets, losses, and readout utilities. +- `evaluate_auc.py`, `evaluate_token_auc.py`: next-token checkpoint evaluation utilities. +- `prepare_data.py`, `prepare_event_dates.py`, `event_date_utils.py`: data preparation helpers. +- `extra_info_types_*.txt`: reusable extra-info type selections. + +## Not Included + +The repository intentionally does not include raw or derived UKB arrays, split files, checkpoints, or run outputs. + +Expected local data files for training normally include: + +```text +ukb_event_data.npy +ukb_other_info.npy +ukb_basic_info.csv +ukb_train_eid.csv +ukb_val_eid.csv +ukb_test_eid.csv +cate_types.csv +``` + +`labels.csv` and `field_ids_enriched.csv` are included because they define the model vocabulary and preparation metadata. + +## Example + +```bash +python train_next_step.py \ + --data_prefix ukb \ + --labels_file labels.csv \ + --extra_info_types_file extra_info_types_exposure_only.txt \ + --target_mode uts \ + --time_mode relative +``` + +For strict next-token Delphi-style training: + +```bash +python train_next_step.py --target_mode delphi2m --readout_name token +``` + +## Exposure Modeling Direction + +For onset-aligned environmental exposure parquet files, the first intended extension is single-stream event enhancement: + +```text +disease event token + pre-onset exposure embedding -> same next-token Transformer +``` + +The key constraint is that a disease event's own pre-onset exposure must not be used to predict that same disease event. diff --git a/backbones.py b/backbones.py new file mode 100644 index 0000000..ea61077 --- /dev/null +++ b/backbones.py @@ -0,0 +1,328 @@ +import math + +import torch +import torch.nn as nn +import torch.nn.functional as F + + +class TimeRoPE(nn.Module): + def __init__(self, dim: int, base: float = 10000.0): + super().__init__() + assert dim % 2 == 0, "RoPE dim must be even" + self.dim = dim + # inv_freq is not trainable, but should move with device. + inv_freq = 1.0 / (base ** (torch.arange(0, dim, 2).float() / dim)) + self.register_buffer("inv_freq", inv_freq, persistent=False) + + def precompute_cache(self, tau: torch.Tensor) -> tuple[torch.Tensor, torch.Tensor]: + t = tau.unsqueeze(-1) # (B, L, 1) + angles = t * self.inv_freq # (B, L, dim//2) + # Pre-expand for heads and interleave once (avoids N_layers repeats) + cos = angles.cos().unsqueeze(1).repeat_interleave(2, dim=-1) + sin = angles.sin().unsqueeze(1).repeat_interleave(2, dim=-1) + return cos, sin # (B, 1, L, dim) + + @staticmethod + def _rotate_half(x: torch.Tensor) -> torch.Tensor: + """Rotate pairs: ``[-x2, x1, -x4, x3, ...]``.""" + x1 = x[..., 0::2] + x2 = x[..., 1::2] + return torch.stack((-x2, x1), dim=-1).flatten(-2) + + @staticmethod + def apply_from_cache( + q: torch.Tensor, + k: torch.Tensor, + rope_cache: tuple[torch.Tensor, torch.Tensor], + ) -> tuple[torch.Tensor, torch.Tensor]: + cos, sin = rope_cache # each (B, 1, L, dim) + q_rot = q * cos + TimeRoPE._rotate_half(q) * sin + k_rot = k * cos + TimeRoPE._rotate_half(k) * sin + return q_rot, k_rot + + def forward( + self, + tau: torch.Tensor, + q: torch.Tensor, + k: torch.Tensor, + ) -> tuple[torch.Tensor, torch.Tensor]: + cache = self.precompute_cache(tau) + return self.apply_from_cache(q, k, cache) + + +class GaussianRBFTimeBasis(nn.Module): + def __init__( + self, + n_bases: int = 16, + max_time_diff: float = 40.0, + ): + super().__init__() + self.n_bases = n_bases + + # Evenly spaced RBF centres for non-negative linear time differences. + # Causal masking enforces query_time >= key_time, so diff is >= 0. + centers = torch.linspace(0.0, max_time_diff, n_bases) + self.register_buffer("centers", centers, + persistent=False) # (n_bases,) + + # Learnable log-widths (initialized to center spacing on linear scale). + init_width = max(max_time_diff / max(n_bases - 1, 1), 1e-3) + init_log_width = math.log(init_width) + self.log_widths = nn.Parameter(torch.full((n_bases,), init_log_width)) + + def precompute_cache(self, tau: torch.Tensor) -> torch.Tensor: + + time_coord = tau.float() # (B, L) + # Pairwise signed difference: query_i - key_j. + diff = time_coord.unsqueeze( + 2) - time_coord.unsqueeze(1) # (B, L_q, L_k) + # Gaussian RBF: exp(-0.5 * ((diff - c) / w)^2) + diff = diff.unsqueeze(-1) # (B, L, L, 1) + widths = self.log_widths.exp() # (n_bases,) + rbf_acts = torch.exp( + -0.5 * ((diff - self.centers) / widths).square() + # (B, L, L, n_bases) + ) + return rbf_acts + + +class TemporalAttention(nn.Module): + def __init__( + self, + n_embd: int, + n_head: int, + n_rbf_bases: int = 16, + dropout: float = 0.0, + use_time_rope: bool = True, + use_rbf_bias: bool = True, + ): + super().__init__() + assert n_embd % n_head == 0, "n_embd must be divisible by n_head" + self.n_head = n_head + self.d_head = n_embd // n_head + self.scale = 1.0 / math.sqrt(self.d_head) + self.use_time_rope = use_time_rope + self.use_rbf_bias = use_rbf_bias + + # QKV projection (fused for efficiency) + self.qkv = nn.Linear(n_embd, 3 * n_embd, bias=False) + # Output projection + self.out_proj = nn.Linear(n_embd, n_embd, bias=False) + + # Layer-specific projection from shared RBF basis activations to per-head attention bias. + self.rbf_proj = nn.Linear(n_rbf_bases, n_head, bias=False) + self.time_bias_scale = nn.Parameter(torch.tensor(0.0)) + + self.resid_drop = nn.Dropout(dropout) + self.reset_parameters() + + def reset_parameters(self) -> None: + """Match the previous version's GPT-style weight initialization.""" + nn.init.normal_(self.qkv.weight, mean=0.0, std=0.02) + nn.init.normal_(self.out_proj.weight, mean=0.0, std=0.02) + nn.init.zeros_(self.rbf_proj.weight) + + def forward( + self, + x: torch.Tensor, + rope_cache: tuple[torch.Tensor, torch.Tensor] | None = None, + rbf_cache: torch.Tensor | None = None, + attn_mask: torch.Tensor | None = None, + ) -> torch.Tensor: + if self.use_time_rope: + assert rope_cache is not None, "rope_cache must be provided when use_time_rope is True" + if self.use_rbf_bias: + assert rbf_cache is not None, "rbf_cache must be provided when use_rbf_bias is True" + + B, L, _ = x.shape + H, D = self.n_head, self.d_head + + # --- QKV ---------------------------------------------------------- + qkv = self.qkv(x).reshape(B, L, 3, H, D).permute(2, 0, 3, 1, 4) + q, k, v = qkv.unbind(0) # each (B, H, L, D) + + # --- Apply RoPE (from shared cache) -------------------------------- + if self.use_time_rope: + q, k = TimeRoPE.apply_from_cache(q, k, rope_cache) + + # Build additive attention bias mask: time bias + causal/padding mask. + time_bias = None + if self.use_rbf_bias: + time_bias = self.rbf_proj(rbf_cache).permute( + 0, 3, 1, 2) # (B, H, L, L) + time_bias = self.time_bias_scale.tanh() * time_bias + + if time_bias is not None and attn_mask is not None: + attn_bias = time_bias + attn_mask.to(time_bias.dtype) + elif time_bias is not None: + attn_bias = time_bias + elif attn_mask is not None: + attn_bias = attn_mask + else: + attn_bias = None + + out = F.scaled_dot_product_attention( + q, + k, + v, + attn_mask=attn_bias, + dropout_p=0.0, + is_causal=False, + scale=self.scale, + ) + + # --- Aggregate & project out -------------------------------------- + out = out.transpose(1, 2).reshape(B, L, H * D) + return self.resid_drop(self.out_proj(out)) + + +class SwiGLU(nn.Module): + def __init__( + self, + n_embd: int, + hidden_dim: int | None = None, + dropout: float = 0.0, + bias: bool = True, + ): + super().__init__() + hidden_dim = hidden_dim if hidden_dim is not None else int( + n_embd * 2.5) + + self.w1 = nn.Linear(n_embd, hidden_dim, bias=bias) # gate path + self.w2 = nn.Linear(n_embd, hidden_dim, bias=bias) # value path + # output projection + self.w3 = nn.Linear(hidden_dim, n_embd, bias=bias) + self.drop = nn.Dropout(dropout) + self.reset_parameters() + + def reset_parameters(self) -> None: + """GPT-style parameter initialization for MLP paths.""" + nn.init.normal_(self.w1.weight, mean=0.0, std=0.02) + nn.init.normal_(self.w2.weight, mean=0.0, std=0.02) + nn.init.normal_(self.w3.weight, mean=0.0, std=0.02) + if self.w1.bias is not None: + nn.init.zeros_(self.w1.bias) + nn.init.zeros_(self.w2.bias) + nn.init.zeros_(self.w3.bias) + + def forward(self, x: torch.Tensor) -> torch.Tensor: + """``(B, L, n_embd) -> (B, L, n_embd)``.""" + return self.drop(self.w3(F.silu(self.w1(x)) * self.w2(x))) + + +class GPTBlock(nn.Module): + def __init__( + self, + n_embd: int, + n_head: int, + + attn_dropout: float = 0.0, + mlp_dropout: float = 0.0, + use_time_rope: bool = False, + use_rbf_bias: bool = False, + n_rbf_bases: int = 16, + ): + super().__init__() + self.attn = TemporalAttention( + n_embd=n_embd, + n_head=n_head, + n_rbf_bases=n_rbf_bases, + dropout=attn_dropout, + use_time_rope=use_time_rope, + use_rbf_bias=use_rbf_bias, + ) + self.mlp = SwiGLU(n_embd=n_embd, dropout=mlp_dropout) + self.ln1 = nn.LayerNorm(n_embd) + self.ln2 = nn.LayerNorm(n_embd) + + def forward( + self, + x: torch.Tensor, + rope_cache: tuple[torch.Tensor, torch.Tensor] | None = None, + rbf_cache: torch.Tensor | None = None, + attn_mask: torch.Tensor | None = None, + ) -> torch.Tensor: + x = x + self.attn(self.ln1(x), rope_cache, rbf_cache, attn_mask) + x = x + self.mlp(self.ln2(x)) + return x + + +class TokenAutoDiscretization(nn.Module): + def __init__( + self, + n_cont_types: int, + n_bins: int, + n_embd: int, + ): + super().__init__() + if n_cont_types <= 0: + raise ValueError(f"n_cont_types must be > 0, got {n_cont_types}") + if n_bins <= 1: + raise ValueError(f"n_bins must be > 1, got {n_bins}") + if n_embd <= 0: + raise ValueError(f"n_embd must be > 0, got {n_embd}") + + self.n_cont_types = n_cont_types + self.n_bins = n_bins + self.n_embd = n_embd + self.weight = nn.Parameter(torch.empty(n_cont_types, n_bins)) + self.bias = nn.Parameter(torch.empty(n_cont_types, n_bins)) + self.bin_emb = nn.Parameter(torch.empty(n_cont_types, n_bins, n_embd)) + self.reset_parameters() + + def reset_parameters(self) -> None: + nn.init.normal_(self.weight, mean=0.0, std=0.02) + nn.init.zeros_(self.bias) + nn.init.normal_(self.bin_emb, mean=0.0, std=0.02) + + def forward( + self, + cont_type_idx: torch.LongTensor, # (N,) + value: torch.Tensor, # (N,) + ) -> torch.Tensor: + if cont_type_idx.dim() != 1: + raise ValueError( + f"cont_type_idx must be 1D, got {tuple(cont_type_idx.shape)}" + ) + if value.dim() != 1: + raise ValueError(f"value must be 1D, got {tuple(value.shape)}") + if cont_type_idx.numel() != value.numel(): + raise ValueError("cont_type_idx and value must have the same length") + + w = self.weight[cont_type_idx] # (N, n_bins) + b = self.bias[cont_type_idx] # (N, n_bins) + e = self.bin_emb[cont_type_idx] # (N, n_bins, D) + logits = value.unsqueeze(-1) * w + b + probs = torch.softmax(logits, dim=-1) + return torch.einsum("nb,nbd->nd", probs, e) + + + +class AgeSinusoidalEncoding(nn.Module): + + def __init__(self, embedding_dim: int): + + super().__init__() + if embedding_dim % 2 != 0: + raise ValueError( + f"Embedding dimension must be an even number, but got {embedding_dim}") + + self.embedding_dim = embedding_dim + + i = torch.arange(0, self.embedding_dim, 2, dtype=torch.float32) + divisor = torch.pow(10000, i / self.embedding_dim) + self.register_buffer('divisor', divisor) + self.linear = nn.Linear(embedding_dim, embedding_dim, bias=False) + + def forward(self, t: torch.Tensor) -> torch.Tensor: + + t_years = t + # Broadcast (B, L, 1) against (1, 1, D/2) to get (B, L, D/2) + args = t_years.unsqueeze(-1) / self.divisor.view(1, 1, -1) + # Interleave cos and sin along the last dimension + output = torch.zeros(t.shape[0], t.shape[1], + self.embedding_dim, device=t.device) + output[:, :, 0::2] = torch.cos(args) + output[:, :, 1::2] = torch.sin(args) + output = self.linear(output) + return output diff --git a/dataset.py b/dataset.py new file mode 100644 index 0000000..2743c73 --- /dev/null +++ b/dataset.py @@ -0,0 +1,674 @@ +# dataset.py +from __future__ import annotations + +from typing import Dict, Iterable, List, Literal, Optional, Tuple + +import numpy as np +import pandas as pd +import torch +from torch.nn.utils.rnn import pad_sequence +from torch.utils.data import Dataset + +from targets import ( + CHECKUP_IDX, + DAYS_PER_YEAR, + NO_EVENT_IDX, + PAD_IDX, + build_all_targets, +) + + +ONE_DAY_YEARS = 1.0 / DAYS_PER_YEAR + + +def load_label_vocab( + labels_file: str, + include_no_event: bool = True, +) -> Tuple[Dict[str, int], Dict[int, str]]: + label_id_to_code: Dict[int, str] = { + PAD_IDX: "", + CHECKUP_IDX: "", + } + if include_no_event: + label_id_to_code[NO_EVENT_IDX] = "" + + offset = NO_EVENT_IDX + 1 if include_no_event else CHECKUP_IDX + 1 + label_code_to_id: Dict[str, int] = {} + with open(labels_file, encoding="utf-8") as f: + for i, line in enumerate(f): + parts = line.strip().split() + if not parts: + continue + idx = offset + i + code = parts[0] + label_code_to_id[code] = idx + label_id_to_code[idx] = code + return label_code_to_id, label_id_to_code + + +def _insert_gap_no_event_tokens( + times_days: np.ndarray, + labels: np.ndarray, + interval_years: float = 5.0, +) -> Tuple[np.ndarray, np.ndarray]: + if len(times_days) < 2: + return times_days, labels + + step_days = interval_years * DAYS_PER_YEAR + unique_times = np.unique(times_days.astype(np.float64)) + extra_times: List[float] = [] + + for i in range(len(unique_times) - 1): + t_left = float(unique_times[i]) + t_right = float(unique_times[i + 1]) + if t_right - t_left <= step_days: + continue + first = np.ceil((t_left + 1e-6) / step_days) * step_days + t = first + while t < t_right - 1e-6: + extra_times.append(t) + t += step_days + + if not extra_times: + return times_days, labels + + extra_arr = np.array(extra_times, dtype=np.float32) + no_event_labels = np.full(len(extra_arr), NO_EVENT_IDX, dtype=np.int64) + all_times = np.concatenate([times_days.astype(np.float32), extra_arr]) + all_labels = np.concatenate([labels.astype(np.int64), no_event_labels]) + order = np.lexsort((all_labels, all_times)) + return all_times[order], all_labels[order] + + +class _ExpoBaseDataset(Dataset): + def __init__( + self, + data_prefix: str = "ukb", + labels_file: str = "labels.csv", + no_event_interval_years: float = 5.0, + include_no_event_in_uts_target: bool = False, + extra_info_types: Iterable[int] | None = None, + ) -> None: + self.data_prefix = data_prefix + self.labels_file = labels_file + self.no_event_interval_years = float(no_event_interval_years) + self.include_no_event_in_uts_target = bool(include_no_event_in_uts_target) + self.requested_extra_info_types = ( + None + if extra_info_types is None + else list(dict.fromkeys(int(t) for t in extra_info_types)) + ) + + self.label_code_to_id, self.label_id_to_code = load_label_vocab( + labels_file, + include_no_event=True, + ) + + event_data = np.load(f"{data_prefix}_event_data.npy") + if event_data.ndim != 2 or event_data.shape[1] < 3: + raise ValueError(f"event_data must have shape (N, 3+), got {event_data.shape}") + event_data = event_data[:, :3].copy() + order = np.lexsort((event_data[:, 2], event_data[:, 1], event_data[:, 0])) + self.event_data = event_data[order] + + basic_table = pd.read_csv(f"{data_prefix}_basic_info.csv", index_col=0) + other_info = np.load(f"{data_prefix}_other_info.npy") + if other_info.ndim != 2 or other_info.shape[1] != 5: + raise ValueError( + f"other_info must have shape (N, 5), got {other_info.shape}" + ) + cate_types = pd.read_csv("cate_types.csv") + required_cate_cols = {"type", "name", "n_categories"} + missing_cate_cols = required_cate_cols - set(cate_types.columns) + if missing_cate_cols: + raise ValueError( + f"cate_types.csv is missing columns: {sorted(missing_cate_cols)}" + ) + + basic_table.index = basic_table.index.astype(np.int64) + + unique_eids = np.unique(self.event_data[:, 0].astype(np.int64)) + basic_table = basic_table.loc[unique_eids] + + self._prepare_sex(basic_table, unique_eids) + self._prepare_other_info(other_info, cate_types, unique_eids) + + max_id_in_vocab = max(self.label_id_to_code.keys()) + max_id_in_data = int(self.event_data[:, 2].max()) if len(self.event_data) > 0 else 0 + max_id_in_data += 1 + self.vocab_size = max(max_id_in_vocab, max_id_in_data) + 1 + + if not self.include_no_event_in_uts_target: + self.ignored_uts_target_ids = {PAD_IDX, CHECKUP_IDX, NO_EVENT_IDX} + else: + self.ignored_uts_target_ids = {PAD_IDX, CHECKUP_IDX} + + def _prepare_sex(self, basic_table: pd.DataFrame, unique_eids: np.ndarray) -> None: + sex_values = pd.to_numeric(basic_table["sex"], errors="coerce").to_numpy() + if np.isnan(sex_values).any(): + raise ValueError("sex column contains missing or non-numeric values") + + sex_values = sex_values.astype(np.int64) + sex_unique = np.unique(sex_values) + if np.all(np.isin(sex_unique, [0, 1])): + sex01 = sex_values + elif np.all(np.isin(sex_unique, [1, 2])): + sex01 = sex_values - 1 + else: + raise ValueError( + f"Unexpected sex values: {sex_unique.tolist()}. Expected {{0,1}} or {{1,2}}." + ) + self.sex_mapping = {int(eid): int(s) for eid, s in zip(unique_eids, sex01)} + + def _prepare_other_info( + self, + other_info: np.ndarray, + cate_types: pd.DataFrame, + unique_eids: np.ndarray, + ) -> None: + other_info = other_info.copy() + other_info[:, 0] = other_info[:, 0].astype(np.int64) + other_info[:, 1] = other_info[:, 1].astype(np.int64) + other_info[:, 3] = other_info[:, 3].astype(np.int64) + + available_types = sorted( + int(t) for t in np.unique(other_info[:, 1]) if int(t) > 0 + ) + if self.requested_extra_info_types is None: + selected_types = available_types + else: + selected_types = self.requested_extra_info_types + missing = sorted(set(selected_types) - set(available_types)) + if missing: + raise ValueError(f"Requested extra_info_types not found: {missing}") + + keep = np.isin(other_info[:, 0].astype(np.int64), unique_eids) + keep &= np.isin(other_info[:, 1].astype(np.int64), selected_types) + other_info = other_info[keep] + + cate_counts = { + int(row["type"]): int(row["n_categories"]) + for _, row in cate_types.iterrows() + } + cate_offsets: Dict[int, int] = {} + next_offset = 0 + for type_id in selected_types: + if type_id in cate_counts: + cate_offsets[type_id] = next_offset + next_offset += cate_counts[type_id] + + kinds = other_info[:, 3].astype(np.int64) + types = other_info[:, 1].astype(np.int64) + cate_rows = kinds == 2 + for type_id in np.unique(types[cate_rows]): + type_id = int(type_id) + if type_id not in cate_offsets: + raise ValueError( + f"type {type_id} appears categorical but is missing from cate_types.csv" + ) + row_mask = cate_rows & (types == type_id) + local_value = other_info[row_mask, 2].astype(np.int64) + other_info[row_mask, 2] = local_value + cate_offsets[type_id] + + cont_type_ids = [ + int(t) + for t in selected_types + if np.any((types == int(t)) & (kinds == 1)) + ] + + self.extra_info_types = selected_types + self.cate_type_offsets = cate_offsets + self.n_types = (max(selected_types) + 1) if selected_types else 1 + self.cont_type_ids = cont_type_ids + self.n_cont_types = len(cont_type_ids) + self.n_categories = next_offset + 1 + + order = np.lexsort((other_info[:, 4], other_info[:, 1], other_info[:, 0])) + other_info = other_info[order] + self.other_info_by_eid: Dict[int, Dict[str, np.ndarray]] = {} + + for eid in unique_eids.astype(np.int64): + self.other_info_by_eid[int(eid)] = { + "other_type": np.zeros(0, dtype=np.int64), + "other_value": np.zeros(0, dtype=np.float32), + "other_value_kind": np.zeros(0, dtype=np.int64), + "other_time": np.zeros(0, dtype=np.float32), + } + + if len(other_info) == 0: + return + + eids, starts = np.unique(other_info[:, 0].astype(np.int64), return_index=True) + ends = np.concatenate([starts[1:], [len(other_info)]]) + for eid_raw, start, end in zip(eids, starts, ends): + rows = other_info[start:end] + self.other_info_by_eid[int(eid_raw)] = { + "other_type": rows[:, 1].astype(np.int64), + "other_value": rows[:, 2].astype(np.float32), + "other_value_kind": rows[:, 3].astype(np.int64), + "other_time": (rows[:, 4].astype(np.float32) / DAYS_PER_YEAR), + } + + def _iter_patient_events( + self, + *, + impute_no_event_gaps: bool, + ) -> Iterable[tuple[int, np.ndarray, np.ndarray]]: + unique_eids, starts = np.unique(self.event_data[:, 0], return_index=True) + ends = np.concatenate([starts[1:], [len(self.event_data)]]) + for eid_raw, start, end in zip(unique_eids, starts, ends): + eid = int(eid_raw) + rows = self.event_data[start:end] + times_days_raw = rows[:, 1].astype(np.float32) + labels_raw = rows[:, 2].astype(np.int64) + + if len(labels_raw) == 0: + yield eid, times_days_raw, labels_raw + continue + + labels_raw = np.where(labels_raw >= NO_EVENT_IDX, labels_raw + 1, labels_raw) + if not impute_no_event_gaps: + yield eid, times_days_raw, labels_raw + continue + + times_days, labels = _insert_gap_no_event_tokens( + times_days_raw, + labels_raw, + interval_years=self.no_event_interval_years, + ) + yield eid, times_days, labels + + def _split_features(self, eid: int) -> Optional[Dict]: + other_info = self.other_info_by_eid.get(eid) + if other_info is None: + return None + return { + "sex": self.sex_mapping[eid], + **other_info, + } + +class NextStepHealthDataset(_ExpoBaseDataset): + """ + Dataset for next-token and next-time-point losses with unified other-info + tokens. + + Returned targets cover both: + - Delphi2MLoss: target_event_seq, target_time_seq + - UniqueTimeSetExponentialLoss: readout_mask, target_dt_unique, target_multi_hot + """ + + CACHE_VERSION = 3 + + def __init__( + self, + data_prefix: str = "ukb", + labels_file: str = "labels.csv", + no_event_interval_years: float = 5.0, + include_no_event_in_uts_target: bool = False, + extra_info_types: Iterable[int] | None = None, + ) -> None: + super().__init__( + data_prefix=data_prefix, + labels_file=labels_file, + no_event_interval_years=no_event_interval_years, + include_no_event_in_uts_target=include_no_event_in_uts_target, + extra_info_types=extra_info_types, + ) + + self.samples: List[Dict] = [] + for eid, times_days, labels in self._iter_patient_events( + impute_no_event_gaps=True, + ): + if len(labels) < 2: + continue + + features = self._split_features(eid) + if features is None: + continue + + target_pack = build_all_targets( + labels=labels, + times_days=times_days, + vocab_size=self.vocab_size, + ignored_uts_target_ids=self.ignored_uts_target_ids, + require_sorted=True, + ) + + self.samples.append({ + "eid": eid, + "event_seq": target_pack.next_token.input_events, + "time_seq": target_pack.next_token.input_times_years, + "target_event_seq": target_pack.next_token.target_events, + "target_time_seq": target_pack.next_token.target_times_years, + "readout_mask": target_pack.unique_time_set.readout_mask, + "target_dt_unique": target_pack.unique_time_set.target_dt_unique, + "target_multi_hot": target_pack.unique_time_set.target_multi_hot, + **features, + }) + + def __len__(self) -> int: + return len(self.samples) + + def __getitem__(self, idx: int) -> Dict: + s = self.samples[idx] + return { + "event_seq": torch.from_numpy(s["event_seq"]).long(), + "time_seq": torch.from_numpy(s["time_seq"]).float(), + "sex": torch.tensor(s["sex"], dtype=torch.long), + "other_type": torch.from_numpy(s["other_type"]).long(), + "other_value": torch.from_numpy(s["other_value"]).float(), + "other_value_kind": torch.from_numpy(s["other_value_kind"]).long(), + "other_time": torch.from_numpy(s["other_time"]).float(), + "target_event_seq": torch.from_numpy(s["target_event_seq"]).long(), + "target_time_seq": torch.from_numpy(s["target_time_seq"]).float(), + "readout_mask": torch.from_numpy(s["readout_mask"]).bool(), + "target_dt_unique": torch.from_numpy(s["target_dt_unique"]).float(), + "target_multi_hot": torch.from_numpy(s["target_multi_hot"]).bool(), + } + + +class AllFutureHealthDataset(_ExpoBaseDataset): + """ + Dataset with unified other-info tokens and DeepHealthV2-style all-future + targets. + + Train samples one query time per patient at each __getitem__ call. + Valid/test use random-but-fixed query points. For each patient with N real + disease events, N - 2 query points are sampled from the eligible observed + time range, with at least one future event after every query. + """ + + CACHE_VERSION = 5 + + def __init__( + self, + data_prefix: str = "ukb", + labels_file: str = "labels.csv", + split: Literal["train", "valid", "test"] = "train", + no_event_interval_years: float = 5.0, + include_no_event_in_uts_target: bool = False, + min_history_events: int = 1, + min_future_events: int = 1, + validation_query_seed: int = 42, + extra_info_types: Iterable[int] | None = None, + ) -> None: + if split not in {"train", "valid", "test"}: + raise ValueError(f"split must be train/valid/test, got {split!r}") + + super().__init__( + data_prefix=data_prefix, + labels_file=labels_file, + no_event_interval_years=no_event_interval_years, + include_no_event_in_uts_target=include_no_event_in_uts_target, + extra_info_types=extra_info_types, + ) + + self.split = split + self.min_history_events = int(min_history_events) + self.min_future_events = int(min_future_events) + self.validation_query_seed = int(validation_query_seed) + self.patients: List[Dict] = [] + self.valid_queries: List[Tuple[int, float]] = [] + validation_rng = None + if split in {"valid", "test"}: + split_offset = 0 if split == "valid" else 1_000_003 + validation_rng = np.random.RandomState(self.validation_query_seed + split_offset) + + for eid, times_days, labels in self._iter_patient_events( + impute_no_event_gaps=False, + ): + times_years = (times_days / DAYS_PER_YEAR).astype(np.float32) + unique_times = np.unique(times_years) + if len(labels) < 2 or len(unique_times) < 2: + continue + + features = self._split_features(eid) + if features is None: + continue + + patient = { + "eid": eid, + "times": times_years, + "labels": labels.astype(np.int64), + "t_obs": float(times_years.max()), + **features, + } + + pidx = len(self.patients) + self.patients.append(patient) + + if split in {"valid", "test"}: + if validation_rng is None: + raise RuntimeError("validation_rng was not initialized") + self.valid_queries.extend( + (pidx, t_query) + for t_query in self._sample_fixed_validation_queries( + patient, + validation_rng, + ) + ) + + if split in {"valid", "test"} and not self.valid_queries: + raise ValueError("No random-but-fixed validation query points were built.") + + def _is_valid_query(self, patient: Dict, t_query: float) -> bool: + times = patient["times"] + labels = patient["labels"] + real_event_mask = ~np.isin( + labels, + np.array([PAD_IDX, CHECKUP_IDX, NO_EVENT_IDX], dtype=np.int64), + ) + n_hist = int((times <= t_query).sum()) + n_future = int(((times > t_query) & real_event_mask).sum()) + return ( + n_hist >= self.min_history_events + and n_future >= self.min_future_events + and patient["t_obs"] > t_query + ) + + def _sample_fixed_validation_queries( + self, + patient: Dict, + rng: np.random.RandomState, + ) -> List[float]: + times = np.asarray(patient["times"], dtype=np.float32) + labels = np.asarray(patient["labels"], dtype=np.int64) + real_event_mask = ~np.isin( + labels, + np.array([PAD_IDX, CHECKUP_IDX, NO_EVENT_IDX], dtype=np.int64), + ) + real_times = np.sort(times[real_event_mask].astype(np.float32, copy=False)) + n_real_events = int(real_times.size) + n_queries = max(0, n_real_events - 2) + if n_queries == 0: + return [] + + min_hist = int(self.min_history_events) + min_future = int(self.min_future_events) + if n_real_events < min_hist + min_future: + return [] + + left = float(real_times[min_hist - 1]) + right_event_time = float(real_times[n_real_events - min_future]) + right = np.nextafter(np.float32(right_event_time), np.float32(-np.inf)) + if not np.isfinite(left) or not np.isfinite(right) or float(right) <= left: + return [] + + queries: List[float] = [] + max_attempts = max(100, n_queries * 50) + for _ in range(max_attempts): + if len(queries) >= n_queries: + break + t_query = float(rng.uniform(left, float(right))) + if self._is_valid_query(patient, t_query): + queries.append(t_query) + + return queries + + def _sample_train_query(self, patient: Dict) -> float: + unique_times = np.unique(patient["times"]) + if len(unique_times) < 2: + raise RuntimeError("Training patient has fewer than two unique times.") + + j = np.random.randint(1, len(unique_times)) + left = float(unique_times[j - 1]) + right = float(unique_times[j]) + + if right - left <= ONE_DAY_YEARS: + t_query = right - ONE_DAY_YEARS + else: + t_query = np.random.uniform(left, right - ONE_DAY_YEARS) + + if not self._is_valid_query(patient, t_query): + t_query = right - 1e-6 + return float(t_query) + + def _build_item(self, patient: Dict, t_query: float) -> Dict: + times = patient["times"] + labels = patient["labels"] + hist = times <= t_query + fut = times > t_query + + return { + "event_seq": torch.from_numpy(labels[hist]).long(), + "time_seq": torch.from_numpy(times[hist]).float(), + "t_query": torch.tensor(t_query, dtype=torch.float32), + "future_targets": torch.from_numpy(labels[fut]).long(), + "future_dt": torch.from_numpy(times[fut] - np.float32(t_query)).float(), + "exposure": torch.tensor(np.float32(patient["t_obs"] - t_query), dtype=torch.float32), + "sex": torch.tensor(patient["sex"], dtype=torch.long), + "other_type": torch.from_numpy(patient["other_type"]).long(), + "other_value": torch.from_numpy(patient["other_value"]).float(), + "other_value_kind": torch.from_numpy(patient["other_value_kind"]).long(), + "other_time": torch.from_numpy(patient["other_time"]).float(), + } + + def __len__(self) -> int: + if self.split == "train": + return len(self.patients) + return len(self.valid_queries) + + def __getitem__(self, idx: int) -> Dict: + if self.split == "train": + patient = self.patients[idx] + t_query = self._sample_train_query(patient) + else: + pidx, t_query = self.valid_queries[idx] + patient = self.patients[pidx] + return self._build_item(patient, t_query) + + +def _collate_common_static(batch: List[Dict]) -> Dict: + return { + "sex": torch.stack([s["sex"] for s in batch]), + "other_type": pad_sequence( + [s["other_type"] for s in batch], + batch_first=True, + padding_value=0, + ), + "other_value": pad_sequence( + [s["other_value"] for s in batch], + batch_first=True, + padding_value=0.0, + ), + "other_value_kind": pad_sequence( + [s["other_value_kind"] for s in batch], + batch_first=True, + padding_value=0, + ), + "other_time": pad_sequence( + [s["other_time"] for s in batch], + batch_first=True, + padding_value=0.0, + ), + } + + +def next_step_collate_fn(batch: List[Dict]) -> Dict: + event_seq = pad_sequence( + [s["event_seq"] for s in batch], + batch_first=True, + padding_value=PAD_IDX, + ) + time_seq = pad_sequence( + [s["time_seq"] for s in batch], + batch_first=True, + padding_value=0.0, + ) + target_event_seq = pad_sequence( + [s["target_event_seq"] for s in batch], + batch_first=True, + padding_value=PAD_IDX, + ) + target_time_seq = pad_sequence( + [s["target_time_seq"] for s in batch], + batch_first=True, + padding_value=0.0, + ) + readout_mask = pad_sequence( + [s["readout_mask"] for s in batch], + batch_first=True, + padding_value=False, + ) + target_dt_unique = pad_sequence( + [s["target_dt_unique"] for s in batch], + batch_first=True, + padding_value=0.0, + ) + target_multi_hot = pad_sequence( + [s["target_multi_hot"] for s in batch], + batch_first=True, + padding_value=False, + ) + + out = { + "event_seq": event_seq, + "time_seq": time_seq, + "padding_mask": event_seq > PAD_IDX, + "target_event_seq": target_event_seq, + "target_time_seq": target_time_seq, + "readout_mask": readout_mask, + "target_dt_unique": target_dt_unique, + "target_multi_hot": target_multi_hot, + } + out.update(_collate_common_static(batch)) + return out + + +def all_future_collate_fn(batch: List[Dict]) -> Dict: + event_seq = pad_sequence( + [s["event_seq"] for s in batch], + batch_first=True, + padding_value=PAD_IDX, + ) + time_seq = pad_sequence( + [s["time_seq"] for s in batch], + batch_first=True, + padding_value=0.0, + ) + future_targets = pad_sequence( + [s["future_targets"] for s in batch], + batch_first=True, + padding_value=PAD_IDX, + ) + future_dt = pad_sequence( + [s["future_dt"] for s in batch], + batch_first=True, + padding_value=0.0, + ) + + out = { + "event_seq": event_seq, + "time_seq": time_seq, + "padding_mask": event_seq > PAD_IDX, + "t_query": torch.stack([s["t_query"] for s in batch]), + "future_targets": future_targets, + "future_dt": future_dt, + "exposure": torch.stack([s["exposure"] for s in batch]), + } + out.update(_collate_common_static(batch)) + return out + + +HealthDataset = NextStepHealthDataset +collate_fn = next_step_collate_fn diff --git a/eval_data.py b/eval_data.py new file mode 100644 index 0000000..f139b3c --- /dev/null +++ b/eval_data.py @@ -0,0 +1,163 @@ +from __future__ import annotations + +from typing import Any, Dict, Iterable, List + +import numpy as np +import torch +from torch.nn.utils.rnn import pad_sequence + +from dataset import AllFutureHealthDataset, HealthDataset +from targets import PAD_IDX + + +class AllFutureSequenceEvalDataset: + """ + Eval-only sequence view for all-future checkpoints. + + All-future training uses the observed history, including CHECKUP state + tokens, without reusing the next-step view that contains imputed + gap tokens. + """ + + def __init__( + self, + data_prefix: str, + labels_file: str, + min_history_events: int = 1, + min_future_events: int = 1, + extra_info_types: Iterable[int] | None = None, + ) -> None: + base = AllFutureHealthDataset( + data_prefix=data_prefix, + labels_file=labels_file, + split="train", + min_history_events=min_history_events, + min_future_events=min_future_events, + extra_info_types=extra_info_types, + ) + + self.base = base + self.label_code_to_id = base.label_code_to_id + self.label_id_to_code = base.label_id_to_code + self.vocab_size = base.vocab_size + self.n_types = base.n_types + self.n_cont_types = base.n_cont_types + self.n_categories = base.n_categories + self.cont_type_ids = base.cont_type_ids + self.extra_info_types = base.extra_info_types + + self.samples: List[Dict[str, Any]] = [] + for patient in base.patients: + labels = np.asarray(patient["labels"], dtype=np.int64) + times = np.asarray(patient["times"], dtype=np.float32) + if labels.size < 2: + continue + input_len = int(labels.size - 1) + self.samples.append( + { + "eid": int(patient["eid"]), + "event_seq": labels[:-1], + "time_seq": times[:-1], + "target_event_seq": labels[1:], + "target_time_seq": times[1:], + "readout_mask": np.ones(input_len, dtype=bool), + "sex": int(patient["sex"]), + "other_type": np.asarray(patient["other_type"], dtype=np.int64), + "other_value": np.asarray(patient["other_value"], dtype=np.float32), + "other_value_kind": np.asarray(patient["other_value_kind"], dtype=np.int64), + "other_time": np.asarray(patient["other_time"], dtype=np.float32), + } + ) + + def __len__(self) -> int: + return len(self.samples) + + def __getitem__(self, idx: int) -> Dict[str, torch.Tensor]: + s = self.samples[idx] + return { + "event_seq": torch.from_numpy(s["event_seq"]).long(), + "time_seq": torch.from_numpy(s["time_seq"]).float(), + "target_event_seq": torch.from_numpy(s["target_event_seq"]).long(), + "target_time_seq": torch.from_numpy(s["target_time_seq"]).float(), + "readout_mask": torch.from_numpy(s["readout_mask"]).bool(), + "sex": torch.tensor(s["sex"], dtype=torch.long), + "other_type": torch.from_numpy(s["other_type"]).long(), + "other_value": torch.from_numpy(s["other_value"]).float(), + "other_value_kind": torch.from_numpy(s["other_value_kind"]).long(), + "other_time": torch.from_numpy(s["other_time"]).float(), + } + + +def load_sequence_eval_dataset( + *, + model_target_mode: str, + data_prefix: str, + labels_file: str, + no_event_interval_years: float, + include_no_event_in_uts_target: bool, + min_history_events: int, + min_future_events: int, + extra_info_types: Iterable[int] | None, +): + mode = str(model_target_mode).lower() + if mode == "next_token": + return HealthDataset( + data_prefix=data_prefix, + labels_file=labels_file, + no_event_interval_years=no_event_interval_years, + include_no_event_in_uts_target=include_no_event_in_uts_target, + extra_info_types=extra_info_types, + ) + if mode == "all_future": + return AllFutureSequenceEvalDataset( + data_prefix=data_prefix, + labels_file=labels_file, + min_history_events=min_history_events, + min_future_events=min_future_events, + extra_info_types=extra_info_types, + ) + raise ValueError(f"Unknown model_target_mode: {model_target_mode!r}") + + +def sequence_eval_collate_fn(batch: List[Dict[str, torch.Tensor]]) -> Dict[str, torch.Tensor]: + event_seq = pad_sequence( + [s["event_seq"] for s in batch], batch_first=True, padding_value=PAD_IDX + ) + time_seq = pad_sequence( + [s["time_seq"] for s in batch], batch_first=True, padding_value=0.0 + ) + target_event_seq = pad_sequence( + [s["target_event_seq"] for s in batch], batch_first=True, padding_value=PAD_IDX + ) + target_time_seq = pad_sequence( + [s["target_time_seq"] for s in batch], batch_first=True, padding_value=0.0 + ) + readout_mask = pad_sequence( + [s["readout_mask"] for s in batch], batch_first=True, padding_value=False + ) + other_type = pad_sequence( + [s["other_type"] for s in batch], batch_first=True, padding_value=0 + ) + other_value = pad_sequence( + [s["other_value"] for s in batch], batch_first=True, padding_value=0.0 + ) + other_value_kind = pad_sequence( + [s["other_value_kind"] for s in batch], batch_first=True, padding_value=0 + ) + other_time = pad_sequence( + [s["other_time"] for s in batch], batch_first=True, padding_value=0.0 + ) + + return { + "event_seq": event_seq, + "time_seq": time_seq, + "padding_mask": event_seq > PAD_IDX, + "target_event_seq": target_event_seq, + "target_time_seq": target_time_seq, + "readout_mask": readout_mask, + "sex": torch.stack([s["sex"] for s in batch]), + "other_type": other_type, + "other_value": other_value, + "other_value_kind": other_value_kind, + "other_time": other_time, + } diff --git a/evaluate_auc.py b/evaluate_auc.py new file mode 100644 index 0000000..96d05b7 --- /dev/null +++ b/evaluate_auc.py @@ -0,0 +1,1423 @@ +""" +Evaluate disease-specific AUC for DeepHealth models. + +This script follows the logic of the Delphi evaluation script supplied by the user: + 1. choose disease tokens of interest from dataset vocabulary; + 2. precompute, for each patient/target occurrence, the latest prediction token + at least `offset` years before the target time; + 3. run model inference by disease chunks to avoid materializing all logits; + 4. compute AUC separately by sex and age bracket; + 5. aggregate age brackets with DeLong variance. + +Efficiency notes: + - transformer/readout inference is executed once and cached; + - disease chunks reuse the cached hidden states and only recompute selected risk-head columns; + - AUC work is parallelized on CPU across disease task blocks using process workers; + - per-sex data are compacted into an event-level table before multiprocessing; + - large per-sex arrays are installed once per worker with fork-style globals on Linux, + avoiding repeated pickling of arrays for every disease. + +Run from the DeepHealth code directory containing dataset.py, models.py, +readouts.py, and train_config.json-compatible checkpoints/configs. +""" +from __future__ import annotations + +import argparse +import contextlib +import json +import math +import multiprocessing as mp +import os +from concurrent.futures import ProcessPoolExecutor +from pathlib import Path +from typing import Any, Dict, List, Optional, Sequence, Tuple + +import numpy as np +import pandas as pd +import torch +from torch.utils.data import DataLoader, Subset +from tqdm.auto import tqdm + +from dataset import HealthDataset +from eval_data import load_sequence_eval_dataset, sequence_eval_collate_fn +from models import DeepHealth +from readouts import build_readout +from targets import PAD_IDX, CHECKUP_IDX, NO_EVENT_IDX + + +# --------------------------------------------------------------------------- +# DeLong AUC utilities, adapted from the supplied Delphi evaluation script +# --------------------------------------------------------------------------- + +def compute_midrank(x: np.ndarray) -> np.ndarray: + """Compute midranks for DeLong variance.""" + x = np.asarray(x, dtype=np.float64) + order = np.argsort(x) + sorted_x = x[order] + n = len(x) + ranks = np.zeros(n, dtype=np.float64) + i = 0 + while i < n: + j = i + while j < n and sorted_x[j] == sorted_x[i]: + j += 1 + ranks[i:j] = 0.5 * (i + j - 1) + i = j + out = np.empty(n, dtype=np.float64) + out[order] = ranks + 1.0 + return out + + +def fast_delong(predictions_sorted_transposed: np.ndarray, label_1_count: int) -> Tuple[np.ndarray, np.ndarray]: + """ + Fast DeLong covariance for ROC AUC. + + This evaluation uses one classifier at a time, so k is normally 1. + In that case np.cov(v01) and np.cov(v10) must be scalar variances. + Do NOT expand them to (m,m)/(n,n) covariance matrices; that is the + source of the broadcast error: + shapes (n_case,n_case) and (n_control,n_control) + """ + predictions_sorted_transposed = np.asarray( + predictions_sorted_transposed, dtype=np.float64) + m = int(label_1_count) + n = int(predictions_sorted_transposed.shape[1] - m) + if m <= 0 or n <= 0: + return np.array([np.nan], dtype=np.float64), np.array([[np.nan]], dtype=np.float64) + + positive_examples = predictions_sorted_transposed[:, :m] + negative_examples = predictions_sorted_transposed[:, m:] + k = int(predictions_sorted_transposed.shape[0]) + + tx = np.empty((k, m), dtype=np.float64) + ty = np.empty((k, n), dtype=np.float64) + tz = np.empty((k, m + n), dtype=np.float64) + for r in range(k): + tx[r] = compute_midrank(positive_examples[r]) + ty[r] = compute_midrank(negative_examples[r]) + tz[r] = compute_midrank(predictions_sorted_transposed[r]) + + aucs = tz[:, :m].sum(axis=1) / m / n - float(m + 1.0) / 2.0 / n + + # DeLong structural components: + # v01: classifier x cases + # v10: classifier x controls + v01 = (tz[:, :m] - tx) / n + v10 = 1.0 - (tz[:, m:] - ty) / m + + if k == 1: + # np.cov on a single row is easy to misuse. The correct covariance + # for one classifier is simply the scalar sample variance over cases + # plus the scalar sample variance over controls. + sx = np.var(v01[0], ddof=1) if m > 1 else 0.0 + sy = np.var(v10[0], ddof=1) if n > 1 else 0.0 + delong_cov = np.array([[sx / m + sy / n]], dtype=np.float64) + else: + # Multiple-classifier general case. rowvar=True: rows are classifiers. + sx = np.cov(v01, rowvar=True) if m > 1 else np.zeros( + (k, k), dtype=np.float64) + sy = np.cov(v10, rowvar=True) if n > 1 else np.zeros( + (k, k), dtype=np.float64) + delong_cov = np.atleast_2d(sx) / m + np.atleast_2d(sy) / n + + return aucs, delong_cov + + +def get_auc_delong_var(control_scores: np.ndarray, case_scores: np.ndarray) -> Tuple[float, float]: + """Return AUC and DeLong variance for controls/class-0 and cases/class-1.""" + control_scores = np.asarray(control_scores, dtype=np.float64) + case_scores = np.asarray(case_scores, dtype=np.float64) + if len(control_scores) == 0 or len(case_scores) == 0: + return np.nan, np.nan + + ground_truth = np.array([1] * len(case_scores) + + [0] * len(control_scores), dtype=np.int8) + predictions = np.concatenate( + [case_scores, control_scores]).astype(np.float64, copy=False) + order = (-ground_truth).argsort() + label_1_count = int(ground_truth.sum()) + + aucs, delong_cov = fast_delong( + predictions[np.newaxis, order], label_1_count) + var = float(np.asarray(delong_cov).reshape(-1)[0]) + return float(aucs[0]), var + + +# --------------------------------------------------------------------------- +# Disease selection +# --------------------------------------------------------------------------- + +SPECIAL_TOKENS = {PAD_IDX, CHECKUP_IDX, NO_EVENT_IDX} + + +def _build_first_occurrence_maps( + dataset: HealthDataset, + subset_indices: np.ndarray, +) -> Tuple[Dict[int, Tuple[np.ndarray, np.ndarray]], np.ndarray, np.ndarray, np.ndarray]: + patient_count = len(subset_indices) + followup_end = np.full(patient_count, -np.inf, dtype=np.float32) + death_time = np.full(patient_count, np.inf, dtype=np.float32) + sex = np.full(patient_count, -1, dtype=np.int8) + + first_lists: Dict[int, List[Tuple[int, float]]] = {} + + for patient_id, dataset_index in enumerate(subset_indices.tolist()): + s = dataset.samples[int(dataset_index)] + + seq_event = np.asarray(s["event_seq"], dtype=np.int64) + seq_time = np.asarray(s["time_seq"], dtype=np.float32) + tgt_event = np.asarray(s["target_event_seq"], dtype=np.int64) + tgt_time = np.asarray(s["target_time_seq"], dtype=np.float32) + + if seq_event.size == 0 or tgt_event.size == 0: + continue + + full_event = np.concatenate([seq_event, tgt_event[-1:]]) + full_time = np.concatenate([seq_time, tgt_time[-1:]]) + + sex[patient_id] = int(s["sex"]) + followup_end[patient_id] = np.max(full_time).astype(np.float32) + + uniq_tokens, first_idx = np.unique(full_event, return_index=True) + + for token, idx in zip(uniq_tokens.tolist(), first_idx.tolist()): + token = int(token) + event_time = float(full_time[int(idx)]) + if token not in first_lists: + first_lists[token] = [] + first_lists[token].append((patient_id, event_time)) + + packed: Dict[int, Tuple[np.ndarray, np.ndarray]] = {} + for token, pairs in first_lists.items(): + if not pairs: + continue + packed[int(token)] = ( + np.asarray([p for p, _ in pairs], dtype=np.int32), + np.asarray([t for _, t in pairs], dtype=np.float32), + ) + + return packed, followup_end, death_time, sex + + +def _get_death_token_ids(dataset: HealthDataset) -> List[int]: + death_ids = [int(dataset.vocab_size) - 1] + print(f"[INFO] death token ids: {death_ids}") + return death_ids + + +def select_disease_tokens( + dataset: HealthDataset, + requested_tokens: Optional[Sequence[int]], + filter_min_total: int, + first_occurrence_by_token: Dict[int, Tuple[np.ndarray, np.ndarray]], +) -> List[int]: + base = [ + int(token) + for token, code in dataset.label_id_to_code.items() + if int(token) not in SPECIAL_TOKENS and not str(code).startswith("<") + ] + base_set = set(base) + print(f"[INFO] Valid disease tokens in current vocabulary: {len(base)}") + + if requested_tokens is not None: + selected = sorted( + set(int(x) for x in requested_tokens if int(x) in base_set and int(x) not in SPECIAL_TOKENS)) + print( + "[INFO] Requested disease tokens provided: " + f"input={len(list(requested_tokens))}, selected={len(selected)} (vocab/SPECIAL filtered).") + print(f"[INFO] Final disease_ids count: {len(selected)}") + return selected + + disease_ids = sorted(base) + if int(filter_min_total) <= 0: + print( + f"[INFO] filter_min_total={int(filter_min_total)} <= 0; keeping all {len(disease_ids)} disease tokens.") + print(f"[INFO] Final disease_ids count: {len(disease_ids)}") + return disease_ids + + print( + f"[INFO] Applying filter_min_total={int(filter_min_total)}: before={len(disease_ids)} tokens.") + print( + "[INFO] Using split first-occurrence patient counts for filter_min_total.") + split_counts = {} + for token, pairs in first_occurrence_by_token.items(): + token = int(token) + if token not in base_set: + continue + split_counts[token] = len(np.unique(pairs[0])) + filtered = [token for token in disease_ids if int( + split_counts.get(token, 0)) > int(filter_min_total)] + print( + "[INFO] First-occurrence count filtering complete: " + f"after={len(filtered)} tokens.") + print(f"[INFO] Final disease_ids count: {len(filtered)}") + return filtered + + +# --------------------------------------------------------------------------- +# Dataset/split/model helpers +# --------------------------------------------------------------------------- + +def load_json_config(path: Optional[str]) -> Dict[str, Any]: + if path is None: + return {} + p = Path(path) + if not p.exists(): + return {} + with p.open("r", encoding="utf-8") as f: + return json.load(f) + + +def cfg_get(args: argparse.Namespace | Dict[str, Any] | None, cfg: Dict[str, Any], name: str, default: Any) -> Any: + """Get a value from CLI args first, then train_config.json, then default. + + This helper intentionally accepts either an argparse.Namespace or a dict. + The earlier version passed cfg as both args and cfg, then tried to access + args.eval_split, which fails because dict has no attributes. + """ + val = None + if args is not None: + if isinstance(args, dict): + val = args.get(name, None) + else: + val = getattr(args, name, None) + if val is not None: + return val + return cfg.get(name, default) + + +def resolve_eval_device(device_arg: Optional[str]) -> torch.device: + """Resolve evaluation device without inheriting train_config.json device.""" + device_name = device_arg or ("cuda" if torch.cuda.is_available() else "cpu") + device = torch.device(device_name) + if device.type == "cuda" and not torch.cuda.is_available(): + raise RuntimeError( + f"Requested device {device_name!r}, but CUDA is not available." + ) + return device + + +def split_indices(n: int, train_ratio: float, val_ratio: float, test_ratio: float, seed: int) -> Tuple[np.ndarray, np.ndarray, np.ndarray]: + total = train_ratio + val_ratio + test_ratio + if not np.isclose(total, 1.0, atol=1e-6): + raise ValueError(f"train/val/test ratios must sum to 1.0, got {total}") + rng = np.random.RandomState(seed) + idx = rng.permutation(n) + n_train = int(n * train_ratio) + n_val = int(n * val_ratio) + return idx[:n_train], idx[n_train:n_train + n_val], idx[n_train + n_val:] + + +def build_model_from_dataset(args: argparse.Namespace, cfg: Dict[str, Any], dataset: HealthDataset) -> DeepHealth: + model_target_mode = str(cfg_get( + args, cfg, "model_target_mode", "next_token")).lower() + if model_target_mode not in {"next_token", "all_future"}: + raise ValueError( + f"model_target_mode must be next_token or all_future, got {model_target_mode!r}" + ) + return DeepHealth( + vocab_size=dataset.vocab_size, + n_embd=int(cfg_get(args, cfg, "n_embd", 120)), + n_head=int(cfg_get(args, cfg, "n_head", 10)), + n_hist_layer=int(cfg_get(args, cfg, "n_hist_layer", 12)), + n_tab_layer=int(cfg_get(args, cfg, "n_tab_layer", 4)), + n_types=dataset.n_types, + n_cont_types=dataset.n_cont_types, + n_categories=dataset.n_categories, + cont_type_ids=dataset.cont_type_ids, + n_bins=int(cfg_get(args, cfg, "n_bins", 16)), + extra_pool_reduce=str(cfg_get(args, cfg, "extra_pool_reduce", "mean")), + target_mode=model_target_mode, + time_mode=str(cfg_get(args, cfg, "time_mode", "relative")), + dist_mode=str(cfg_get(args, cfg, "dist_mode", "exponential")), + dropout=float(cfg_get(args, cfg, "dropout", 0.0)), + ) + + +def _extract_state_dict(ckpt: Any) -> Dict[str, Any]: + if isinstance(ckpt, dict) and "model" in ckpt: + return ckpt["model"] + elif isinstance(ckpt, dict) and "state_dict" in ckpt: + return ckpt["state_dict"] + return ckpt + + +def load_checkpoint_state_dict(checkpoint_path: str, map_location: str | torch.device = "cpu") -> Dict[str, Any]: + ckpt = torch.load(checkpoint_path, map_location=map_location) + state = _extract_state_dict(ckpt) + if not isinstance(state, dict): + raise TypeError( + f"Unsupported checkpoint payload type: {type(state)}") + return state + + +def resolve_dist_mode_for_checkpoint(cfg_dist_mode: str, state_dict: Dict[str, Any]) -> str: + mode = str(cfg_dist_mode).lower() + has_rho_head = any(str(k).startswith("rho_head.") + for k in state_dict.keys()) + has_rho_death_head = any(str(k).startswith("rho_death_head.") + for k in state_dict.keys()) + + if has_rho_head and mode != "weibull": + print( + "[WARN] Checkpoint contains rho_head weights; overriding dist_mode to 'weibull' for evaluation.") + return "weibull" + if has_rho_death_head and mode != "mixed": + print( + "[WARN] Checkpoint contains rho_death_head weights; overriding dist_mode to 'mixed' for evaluation.") + return "mixed" + if (not has_rho_head) and mode == "weibull": + print( + "[WARN] dist_mode is 'weibull' but checkpoint has no rho_head weights; overriding dist_mode to 'exponential'.") + return "exponential" + if (not has_rho_death_head) and mode == "mixed": + print( + "[WARN] dist_mode is 'mixed' but checkpoint has no rho_death_head weights; overriding dist_mode to 'exponential'.") + return "exponential" + return mode + + +def load_model_state( + model: torch.nn.Module, + checkpoint_path: str, + device: torch.device, + state_dict: Optional[Dict[str, Any]] = None, +) -> None: + state = state_dict if state_dict is not None else load_checkpoint_state_dict( + checkpoint_path, map_location=device) + + model.load_state_dict(state, strict=True) + + +def make_eval_subset(dataset: HealthDataset, args: argparse.Namespace | Dict[str, Any] | None, cfg: Dict[str, Any]) -> Tuple[Subset, np.ndarray]: + train_ratio = float(cfg_get(args, cfg, "train_ratio", 0.7)) + val_ratio = float(cfg_get(args, cfg, "val_ratio", 0.15)) + test_ratio = float(cfg_get(args, cfg, "test_ratio", 0.15)) + seed = int(cfg_get(args, cfg, "seed", 42)) + eval_split = str(cfg_get(args, cfg, "eval_split", "test")).lower() + dataset_subset_size = cfg_get(args, cfg, "dataset_subset_size", None) + + train_idx, val_idx, test_idx = split_indices( + len(dataset), train_ratio, val_ratio, test_ratio, seed) + split_map = { + "train": train_idx, + "val": val_idx, + "valid": val_idx, + "validation": val_idx, + "test": test_idx, + "all": np.arange(len(dataset)), + } + if eval_split not in split_map: + raise ValueError( + f"eval_split must be one of {sorted(split_map)}, got {eval_split!r}") + + indices = split_map[eval_split] + if dataset_subset_size is not None and int(dataset_subset_size) > 0: + indices = indices[: int(dataset_subset_size)] + return Subset(dataset, indices.tolist()), np.asarray(indices, dtype=np.int64) + + +def validate_dataset_metadata(dataset: HealthDataset, cfg: Dict[str, Any]) -> None: + meta = cfg.get("dataset_metadata") + if not isinstance(meta, dict): + return + + actual: Dict[str, Any] = { + "vocab_size": int(dataset.vocab_size), + "n_types": int(dataset.n_types), + "n_cont_types": int(dataset.n_cont_types), + "n_categories": int(dataset.n_categories), + "cont_type_ids": [int(x) for x in dataset.cont_type_ids], + "extra_info_types": [int(x) for x in dataset.extra_info_types], + } + mismatches = [ + f"{key}: train_config={meta.get(key)!r}, current_dataset={value!r}" + for key, value in actual.items() + if key in meta and meta.get(key) != value + ] + if mismatches: + raise RuntimeError( + "Current dataset metadata does not match train_config.json. " + "Use the same prepared data and extra_info_types as training. " + + "; ".join(mismatches) + ) + + +# --------------------------------------------------------------------------- +# Batched inference + cached hidden states +# --------------------------------------------------------------------------- + + +def _numpy_hidden_dtype(name: str) -> np.dtype: + name = str(name).lower() + if name in {"float16", "fp16", "half"}: + return np.float16 + if name in {"bfloat16", "bf16"}: + # NumPy has limited bfloat16 support; store as fp16 for compact CPU cache. + return np.float16 + if name in {"float32", "fp32", "single"}: + return np.float32 + raise ValueError( + f"hidden_cache_dtype must be float16 or float32, got {name!r}") + + +@torch.inference_mode() +def infer_readout_hidden( + model: DeepHealth, + loader: DataLoader, + device: torch.device, + model_target_mode: str, + readout_name: str, + readout_reduce: str, + use_amp: bool, + hidden_cache_dtype: str = "float16", +) -> Tuple[np.ndarray, Dict[str, np.ndarray]]: + """Cache per-position hidden states used by the unchanged AUC logic.""" + model_target_mode = str(model_target_mode).lower() + if model_target_mode not in {"next_token", "all_future"}: + raise ValueError( + f"model_target_mode must be next_token or all_future, got {model_target_mode!r}" + ) + + readout = None + if model_target_mode == "next_token" and readout_name == "same_time_group_end": + readout = build_readout("same_time_group_end", + reduce=readout_reduce).to(device) + elif model_target_mode == "next_token": + readout = build_readout(readout_name).to(device) + if readout is not None: + readout.eval() + + hidden_parts: List[np.ndarray] = [] + arrays: Dict[str, List[np.ndarray]] = { + "event_seq": [], + "time_seq": [], + "target_event_seq": [], + "target_time_seq": [], + "padding_mask": [], + "readout_mask": [], + "sex": [], + } + max_len = 0 + out_dtype = _numpy_hidden_dtype(hidden_cache_dtype) + autocast_enabled = bool(use_amp and device.type == "cuda") + + for batch in tqdm(loader, desc="Model/readout inference", leave=False, dynamic_ncols=True): + batch_dev = { + k: (v.to(device, non_blocking=True) + if isinstance(v, torch.Tensor) else v) + for k, v in batch.items() + } + event_seq = batch_dev["event_seq"] + time_seq = batch_dev["time_seq"] + padding_mask = batch_dev["padding_mask"] + + amp_context = ( + torch.autocast(device_type=device.type, dtype=torch.float16) + if autocast_enabled else contextlib.nullcontext() + ) + with amp_context: + if model_target_mode == "all_future": + batch_size, seq_len = event_seq.shape + hidden = torch.zeros( + batch_size, + seq_len, + model.n_embd, + device=event_seq.device, + dtype=torch.float32, + ) + for pos in range(seq_len): + active = padding_mask[:, pos].bool() + if not active.any(): + continue + hidden_pos = model( + event_seq=event_seq[active], + time_seq=time_seq[active], + sex=batch_dev["sex"][active], + padding_mask=padding_mask[active], + t_query=time_seq[active, pos], + other_type=batch_dev["other_type"][active], + other_value=batch_dev["other_value"][active], + other_value_kind=batch_dev["other_value_kind"][active], + other_time=batch_dev["other_time"][active], + target_mode="all_future", + ) + hidden[active, pos, :] = hidden_pos.float() + readout_mask_np = batch["padding_mask"].cpu().numpy() + else: + hidden_raw = model( + event_seq=event_seq, + time_seq=time_seq, + sex=batch_dev["sex"], + padding_mask=padding_mask, + other_type=batch_dev["other_type"], + other_value=batch_dev["other_value"], + other_value_kind=batch_dev["other_value_kind"], + other_time=batch_dev["other_time"], + target_mode="next_token", + ) + ro = readout( + hidden=hidden_raw, + time_seq=time_seq, + padding_mask=padding_mask, + readout_mask=batch_dev["readout_mask"], + ) + hidden = ro.hidden + readout_mask_np = ro.readout_mask.detach().cpu().numpy() + + h = hidden.detach().cpu().numpy().astype(out_dtype, copy=False) + hidden_parts.append(h) + max_len = max(max_len, h.shape[1]) + + for k in arrays: + if k == "sex": + arrays[k].append( + batch[k].cpu().numpy().astype(np.int8, copy=False)) + else: + arrays[k].append(batch[k].cpu().numpy()) + arrays["readout_mask"][-1] = readout_mask_np + + def pad_3d(parts: List[np.ndarray], fill: float = 0.0) -> np.ndarray: + out = np.full( + (sum(x.shape[0] for x in parts), max_len, parts[0].shape[2]), + fill, + dtype=out_dtype, + ) + s = 0 + for x in parts: + out[s:s + x.shape[0], :x.shape[1], :] = x + s += x.shape[0] + return out + + def pad_2d(parts: List[np.ndarray], fill: Any = 0, dtype: Optional[np.dtype] = None) -> np.ndarray: + dtype = dtype or parts[0].dtype + out = np.full((sum(x.shape[0] + for x in parts), max_len), fill, dtype=dtype) + s = 0 + for x in parts: + out[s:s + x.shape[0], :x.shape[1]] = x + s += x.shape[0] + return out + + hidden_all = pad_3d(hidden_parts) + arr_out = { + "event_seq": pad_2d(arrays["event_seq"], PAD_IDX, np.int64), + "time_seq": pad_2d(arrays["time_seq"], 0.0, np.float32), + "target_event_seq": pad_2d(arrays["target_event_seq"], PAD_IDX, np.int64), + "target_time_seq": pad_2d(arrays["target_time_seq"], 0.0, np.float32), + "padding_mask": pad_2d(arrays["padding_mask"], False, bool), + "readout_mask": pad_2d(arrays["readout_mask"], False, bool), + "sex": np.concatenate(arrays["sex"], axis=0), + } + return hidden_all, arr_out + + +@torch.inference_mode() +def compute_logits_for_disease_chunk( + model: DeepHealth, + hidden_all: np.ndarray, + disease_ids: Sequence[int], + device: torch.device, + logit_batch_size: int, + use_amp: bool, +) -> np.ndarray: + """Project cached hidden states to only the requested disease columns.""" + n = int(hidden_all.shape[0]) + logit_batch_size = max(1, int(logit_batch_size)) + disease_ids = [int(x) for x in disease_ids] + + compute_dtype = torch.float16 if ( + device.type == "cuda" and use_amp) else torch.float32 + weight = model.risk_head.weight[disease_ids].detach().to( + device=device, dtype=compute_dtype) + bias = None + if model.risk_head.bias is not None: + bias = model.risk_head.bias[disease_ids].detach().to( + device=device, dtype=compute_dtype) + + parts: List[np.ndarray] = [] + for start in tqdm(range(0, n, logit_batch_size), desc="Risk-head projection", leave=False, dynamic_ncols=True): + end = min(start + logit_batch_size, n) + h = torch.from_numpy(hidden_all[start:end]).to( + device=device, dtype=compute_dtype, non_blocking=True) + logits = torch.matmul(h, weight.t()) + if bias is not None: + logits = logits + bias + parts.append(logits.float().cpu().numpy().astype( + np.float32, copy=False)) + del h, logits + return np.concatenate(parts, axis=0) + + +# --------------------------------------------------------------------------- +# CPU-parallel calibration AUC +# --------------------------------------------------------------------------- + +_WORKER: Dict[str, Any] = {} + + +def _build_flat_eval_table( + p_sex: np.ndarray, + time_seq: np.ndarray, + target_time_seq: np.ndarray, + target_event_seq: np.ndarray, + padding_mask: np.ndarray, + readout_mask: np.ndarray, + offset: float, + valid_target_min_id: int, + age_groups: np.ndarray, +) -> Dict[str, np.ndarray]: + """ + Build a compact event-level table for AUC evaluation. + + The previous version kept 2D patient x position arrays and each disease task + repeatedly scanned them. This table keeps only eligible target occurrences: + - target event is a real disease/event target; + - a valid readout token exists at least `offset` years before target time; + - the prediction token itself is valid and readout-valid; + - predicted age falls inside the requested age brackets. + + The disease-specific logic is unchanged; this only changes the physical layout + of the data to make CPU multiprocessing cheaper and more cache-friendly. + """ + if len(age_groups) < 2: + raise ValueError("age_groups must contain at least two values") + age_start = float(age_groups[0]) + age_step = float(age_groups[1] - age_groups[0]) + n_age = int(len(age_groups)) + + # Raw valid-target table is used only to decide which patients are cases for + # a disease. This intentionally happens before offset/age filtering, matching + # the supplied Delphi logic: a patient who ever has disease k is not a control + # for k, even if that occurrence later lacks a valid prediction point. + raw_patient_idx, raw_target_idx = np.where( + target_event_seq > int(valid_target_min_id)) + raw_target_event = target_event_seq[raw_patient_idx, raw_target_idx].astype( + np.int32, copy=False) + raw_sort_order = np.argsort(raw_target_event, kind="mergesort") + raw_sorted_target_event = raw_target_event[raw_sort_order] + raw_patient_idx = raw_patient_idx.astype(np.int32, copy=False) + + valid_pred_pos = ( + (time_seq[:, :, None] <= (target_time_seq[:, None, :] - float(offset))) + & readout_mask[:, :, None] + ) + pos_index = np.arange(time_seq.shape[1], dtype=np.int32)[None, :, None] + pred_idx_precompute = np.where( + valid_pred_pos, pos_index, -1).max(axis=1).astype(np.int32) + + candidate = (target_event_seq > int(valid_target_min_id)) & ( + pred_idx_precompute >= 0) + patient_idx, target_idx = np.where(candidate) + if patient_idx.size == 0: + return { + "patient": np.empty(0, dtype=np.int32), + "target_event": np.empty(0, dtype=np.int32), + "pred_idx": np.empty(0, dtype=np.int32), + "age_bin": np.empty(0, dtype=np.int16), + "target_time": np.empty(0, dtype=np.float32), + "sort_order": np.empty(0, dtype=np.int64), + "sorted_target_event": np.empty(0, dtype=np.int32), + "raw_patient": raw_patient_idx, + "raw_sort_order": raw_sort_order.astype(np.int64, copy=False), + "raw_sorted_target_event": raw_sorted_target_event.astype(np.int32, copy=False), + "p_sex": p_sex, + "age_groups": age_groups.astype(np.float32, copy=False), + "n_patients": np.int32(time_seq.shape[0]), + } + + pred_idx = pred_idx_precompute[patient_idx, target_idx] + pred_ok = padding_mask[patient_idx, + pred_idx] & readout_mask[patient_idx, pred_idx] + if not np.any(pred_ok): + return { + "patient": np.empty(0, dtype=np.int32), + "target_event": np.empty(0, dtype=np.int32), + "pred_idx": np.empty(0, dtype=np.int32), + "age_bin": np.empty(0, dtype=np.int16), + "target_time": np.empty(0, dtype=np.float32), + "sort_order": np.empty(0, dtype=np.int64), + "sorted_target_event": np.empty(0, dtype=np.int32), + "raw_patient": raw_patient_idx, + "raw_sort_order": raw_sort_order.astype(np.int64, copy=False), + "raw_sorted_target_event": raw_sorted_target_event.astype(np.int32, copy=False), + "p_sex": p_sex, + "age_groups": age_groups.astype(np.float32, copy=False), + "n_patients": np.int32(time_seq.shape[0]), + } + + patient_idx = patient_idx[pred_ok].astype(np.int32, copy=False) + target_idx = target_idx[pred_ok] + pred_idx = pred_idx[pred_ok].astype(np.int32, copy=False) + + pred_age = time_seq[patient_idx, pred_idx].astype(np.float32, copy=False) + age_bin = np.floor((pred_age - age_start) / age_step).astype(np.int16) + age_ok = (age_bin >= 0) & (age_bin < n_age) + if not np.any(age_ok): + return { + "patient": np.empty(0, dtype=np.int32), + "target_event": np.empty(0, dtype=np.int32), + "pred_idx": np.empty(0, dtype=np.int32), + "age_bin": np.empty(0, dtype=np.int16), + "target_time": np.empty(0, dtype=np.float32), + "sort_order": np.empty(0, dtype=np.int64), + "sorted_target_event": np.empty(0, dtype=np.int32), + "raw_patient": raw_patient_idx, + "raw_sort_order": raw_sort_order.astype(np.int64, copy=False), + "raw_sorted_target_event": raw_sorted_target_event.astype(np.int32, copy=False), + "p_sex": p_sex, + "age_groups": age_groups.astype(np.float32, copy=False), + "n_patients": np.int32(time_seq.shape[0]), + } + + patient_idx = patient_idx[age_ok] + target_idx = target_idx[age_ok] + pred_idx = pred_idx[age_ok] + age_bin = age_bin[age_ok] + target_event = target_event_seq[patient_idx, + target_idx].astype(np.int32, copy=False) + target_time = target_time_seq[patient_idx, + target_idx].astype(np.float32, copy=False) + + sort_order = np.argsort(target_event, kind="mergesort") + sorted_target_event = target_event[sort_order] + + return { + "patient": patient_idx.astype(np.int32, copy=False), + "target_event": target_event, + "pred_idx": pred_idx.astype(np.int32, copy=False), + "age_bin": age_bin.astype(np.int16, copy=False), + "target_time": target_time, + "sort_order": sort_order.astype(np.int64, copy=False), + "sorted_target_event": sorted_target_event.astype(np.int32, copy=False), + "raw_patient": raw_patient_idx, + "raw_sort_order": raw_sort_order.astype(np.int64, copy=False), + "raw_sorted_target_event": raw_sorted_target_event.astype(np.int32, copy=False), + "p_sex": p_sex, + "age_groups": age_groups.astype(np.float32, copy=False), + "n_patients": np.int32(time_seq.shape[0]), + } + + +def _init_auc_worker_flat( + patient: np.ndarray, + target_event: np.ndarray, + pred_idx: np.ndarray, + age_bin: np.ndarray, + target_time: np.ndarray, + sort_order: np.ndarray, + sorted_target_event: np.ndarray, + raw_patient: np.ndarray, + raw_sort_order: np.ndarray, + raw_sorted_target_event: np.ndarray, + p_sex: np.ndarray, + age_groups: np.ndarray, + n_patients: int, +): + # Prevent BLAS/OpenMP oversubscription when many worker processes are active. + os.environ.setdefault("OMP_NUM_THREADS", "1") + os.environ.setdefault("MKL_NUM_THREADS", "1") + os.environ.setdefault("OPENBLAS_NUM_THREADS", "1") + os.environ.setdefault("NUMEXPR_NUM_THREADS", "1") + + _WORKER.clear() + _WORKER.update({ + "patient": patient, + "target_event": target_event, + "pred_idx": pred_idx, + "age_bin": age_bin, + "target_time": target_time, + "sort_order": sort_order, + "sorted_target_event": sorted_target_event, + "raw_patient": raw_patient, + "raw_sort_order": raw_sort_order, + "raw_sorted_target_event": raw_sorted_target_event, + "p_sex": p_sex, + "age_groups": age_groups, + "n_patients": int(n_patients), + }) + + +def _case_indices_for_token(token: int) -> np.ndarray: + sorted_target_event = _WORKER["sorted_target_event"] + sort_order = _WORKER["sort_order"] + left = np.searchsorted(sorted_target_event, int(token), side="left") + right = np.searchsorted(sorted_target_event, int(token), side="right") + if right <= left: + return np.empty(0, dtype=np.int64) + return sort_order[left:right] + + +def _raw_case_patients_for_token(token: int) -> np.ndarray: + raw_sorted_target_event = _WORKER["raw_sorted_target_event"] + raw_sort_order = _WORKER["raw_sort_order"] + raw_patient = _WORKER["raw_patient"] + left = np.searchsorted(raw_sorted_target_event, int(token), side="left") + right = np.searchsorted(raw_sorted_target_event, int(token), side="right") + if right <= left: + return np.empty(0, dtype=np.int32) + return np.unique(raw_patient[raw_sort_order[left:right]]) + + +def _calibration_auc_one_disease_flat(task: Tuple[int, int]) -> List[Dict[str, Any]]: + j, token = task + patient = _WORKER["patient"] + pred_idx = _WORKER["pred_idx"] + age_bin = _WORKER["age_bin"] + target_time = _WORKER["target_time"] + p_sex = _WORKER["p_sex"] + age_groups = _WORKER["age_groups"] + n_patients = _WORKER["n_patients"] + + case_idx = _case_indices_for_token(int(token)) + if case_idx.size < 2: + return [] + + case_patients = _raw_case_patients_for_token(int(token)) + if case_patients.size == 0: + return [] + + patient_has_case = np.zeros(n_patients, dtype=bool) + patient_has_case[case_patients] = True + + # Controls follow the supplied Delphi logic: any eligible target occurrence from + # a patient who never has this disease token in the evaluated target table. + control_idx = np.flatnonzero(~patient_has_case[patient]) + if control_idx.size == 0: + return [] + + out: List[Dict[str, Any]] = [] + for b, aa in enumerate(age_groups): + case_b = case_idx[age_bin[case_idx] == b] + control_b = control_idx[age_bin[control_idx] == b] + if case_b.size == 0 or control_b.size == 0: + continue + + # Match previous deterministic one-occurrence-per-patient behavior within + # each age bracket, separately for cases and controls. This avoids letting + # high-utilization patients dominate the AUC. + _, case_first = np.unique(patient[case_b], return_index=True) + _, control_first = np.unique(patient[control_b], return_index=True) + case_keep = case_b[case_first] + control_keep = control_b[control_first] + if case_keep.size == 0 or control_keep.size == 0: + continue + + # Delphi2M-aligned AUC score: use disease-specific eta/logit only. + # Prediction offset filters eligible prediction tokens but does not enter the score. + case_scores = p_sex[patient[case_keep], pred_idx[case_keep], j].astype( + np.float64, copy=False) + control_scores = p_sex[patient[control_keep], pred_idx[control_keep], j].astype( + np.float64, copy=False) + if case_scores.size == 0 or control_scores.size == 0: + continue + + auc_value, auc_var = get_auc_delong_var(control_scores, case_scores) + + out.append({ + "token": int(token), + "auc": float(auc_value), + "auc_delong": float(auc_value), + "auc_variance_delong": float(auc_var), + "age": float(aa), + "age_right": float(aa + (age_groups[1] - age_groups[0])), + "n_healthy": int(control_scores.size), + "n_diseased": int(case_scores.size), + "mean_target_time": float(np.mean(target_time[case_keep])) if case_keep.size else np.nan, + }) + return out + + +def _calibration_auc_task_block(tasks: Sequence[Tuple[int, int]]) -> List[Dict[str, Any]]: + rows: List[Dict[str, Any]] = [] + for task in tasks: + rows.extend(_calibration_auc_one_disease_flat(task)) + return rows + + +def _split_tasks_for_workers( + tasks: Sequence[Tuple[int, int]], + effective_workers: int, + task_chunk_size: int, +) -> List[List[Tuple[int, int]]]: + if not tasks: + return [] + if task_chunk_size <= 0: + # Enough chunks to keep workers busy without creating one Future per disease. + task_chunk_size = max(1, math.ceil( + len(tasks) / max(1, effective_workers * 4))) + return [list(tasks[i:i + task_chunk_size]) for i in range(0, len(tasks), task_chunk_size)] + + +def compute_auc_chunk_parallel( + p_chunk: np.ndarray, + arrays: Dict[str, np.ndarray], + disease_ids: Sequence[int], + sex_value: int, + sex_name: str, + age_groups: np.ndarray, + offset: float, + valid_target_min_id: int, + num_workers: int, + auc_task_chunk_size: int = 0, +) -> List[Dict[str, Any]]: + sex_mask = arrays["sex"] == sex_value + if not np.any(sex_mask): + return [] + + flat = _build_flat_eval_table( + p_sex=p_chunk[sex_mask], + time_seq=arrays["time_seq"][sex_mask], + target_time_seq=arrays["target_time_seq"][sex_mask], + target_event_seq=arrays["target_event_seq"][sex_mask], + padding_mask=arrays["padding_mask"][sex_mask], + readout_mask=arrays["readout_mask"][sex_mask], + offset=offset, + valid_target_min_id=valid_target_min_id, + age_groups=age_groups, + ) + if flat["patient"].size == 0: + return [] + + # Skip diseases with no cases in this sex before sending tasks to workers. + sorted_events = flat["sorted_target_event"] + tasks = [] + for j, token in enumerate(disease_ids): + left = np.searchsorted(sorted_events, int(token), side="left") + right = np.searchsorted(sorted_events, int(token), side="right") + if right - left >= 2: + tasks.append((j, int(token))) + if not tasks: + return [] + + effective_workers = max(1, min(int(num_workers), len(tasks))) + if effective_workers <= 1: + _init_auc_worker_flat( + flat["patient"], flat["target_event"], flat["pred_idx"], flat["age_bin"], + flat["target_time"], flat["sort_order"], flat["sorted_target_event"], + flat["raw_patient"], flat["raw_sort_order"], flat["raw_sorted_target_event"], + flat["p_sex"], flat["age_groups"], int(flat["n_patients"]), + ) + nested = [_calibration_auc_one_disease_flat(t) for t in tqdm( + tasks, desc=f"AUC {sex_name}", leave=False, dynamic_ncols=True)] + else: + ctx = mp.get_context("fork") if hasattr( + os, "fork") else mp.get_context() + task_blocks = _split_tasks_for_workers( + tasks, effective_workers, int(auc_task_chunk_size)) + with ProcessPoolExecutor( + max_workers=effective_workers, + mp_context=ctx, + initializer=_init_auc_worker_flat, + initargs=( + flat["patient"], flat["target_event"], flat["pred_idx"], flat["age_bin"], + flat["target_time"], flat["sort_order"], flat["sorted_target_event"], + flat["raw_patient"], flat["raw_sort_order"], flat["raw_sorted_target_event"], + flat["p_sex"], flat["age_groups"], int(flat["n_patients"]), + ), + ) as ex: + nested = list(tqdm( + ex.map(_calibration_auc_task_block, task_blocks), + total=len(task_blocks), + desc=f"AUC {sex_name}", + leave=False, + dynamic_ncols=True, + )) + + out: List[Dict[str, Any]] = [] + for rows in nested: + for r in rows: + r["sex"] = sex_name + r["offset"] = float(offset) + out.append(r) + return out + + +# --------------------------------------------------------------------------- +# Pipeline +# --------------------------------------------------------------------------- + +def evaluate_auc_pipeline( + model: DeepHealth, + loader: DataLoader, + dataset: HealthDataset, + output_path: Optional[str], + diseases_of_interest: Optional[Sequence[int]], + filter_min_total: int, + first_occurrence_by_token: Dict[int, Tuple[np.ndarray, np.ndarray]], + include_death: bool, + exclude_death: bool, + disease_chunk_size: int, + age_groups: np.ndarray, + offsets: Sequence[float], + device: torch.device, + model_target_mode: str, + readout_name: str, + readout_reduce: str, + num_workers_auc: int, + use_amp: bool, + auc_task_chunk_size: int = 0, + hidden_cache_dtype: str = "float16", + logit_batch_size: int = 256, +) -> Tuple[pd.DataFrame, pd.DataFrame]: + model.eval().to(device) + + disease_ids = select_disease_tokens( + dataset=dataset, + requested_tokens=diseases_of_interest, + filter_min_total=filter_min_total, + first_occurrence_by_token=first_occurrence_by_token, + ) + disease_ids = [int(k) for k in disease_ids if 0 <= + int(k) < dataset.vocab_size] + + death_token_ids = _get_death_token_ids(dataset) + if (not bool(include_death)) or bool(exclude_death): + before = len(disease_ids) + death_set = set(int(x) for x in death_token_ids) + disease_ids = [int(x) for x in disease_ids if int(x) not in death_set] + print( + "[INFO] Death exclusion applied on final disease_ids: " + f"include_death={bool(include_death)}, exclude_death={bool(exclude_death)}, " + f"before={before}, after={len(disease_ids)}.") + + if not disease_ids: + raise ValueError("No diseases selected for evaluation.") + + if disease_chunk_size is None or int(disease_chunk_size) <= 0: + disease_chunk_size = len(disease_ids) + disease_chunk_size = max(1, int(disease_chunk_size)) + + num_chunks = math.ceil(len(disease_ids) / disease_chunk_size) + chunks = np.array_split(np.asarray( + disease_ids, dtype=np.int64), num_chunks) + print( + f"Evaluating {len(disease_ids)} disease tokens in {len(chunks)} chunk(s).") + print("Using Delphi2M-aligned rate/logit score for AUC.") + print("AUC score = disease-specific eta at the latest eligible prediction token.") + print("Prediction offset controls eligibility only and does not enter the score.") + print(f"Evaluating prediction offsets: {', '.join(f'{x:g}' for x in offsets)} years.") + + # In current dataset sex is normalized to 0/1. UKB convention after normalization: 0=female, 1=male. + sex_items = [("female", 0), ("male", 1)] + all_rows: List[Dict[str, Any]] = [] + + valid_target_min_id = CHECKUP_IDX if NO_EVENT_IDX >= dataset.vocab_size else CHECKUP_IDX + # If NO_EVENT exists and should not be a disease/control target, require target > NO_EVENT_IDX. + if NO_EVENT_IDX in dataset.label_id_to_code and dataset.label_id_to_code.get(NO_EVENT_IDX) == "": + valid_target_min_id = NO_EVENT_IDX + + hidden_all, arrays = infer_readout_hidden( + model=model, + loader=loader, + device=device, + model_target_mode=model_target_mode, + readout_name=readout_name, + readout_reduce=readout_reduce, + use_amp=use_amp, + hidden_cache_dtype=hidden_cache_dtype, + ) + print( + f"Cached readout hidden: shape={hidden_all.shape}, dtype={hidden_all.dtype}") + + for chunk_idx, chunk in enumerate(tqdm(chunks, desc="Processing disease chunks", dynamic_ncols=True)): + p_chunk = compute_logits_for_disease_chunk( + model=model, + hidden_all=hidden_all, + disease_ids=chunk.tolist(), + device=device, + logit_batch_size=logit_batch_size, + use_amp=use_amp, + ) + for offset in offsets: + for sex_name, sex_value in sex_items: + rows = compute_auc_chunk_parallel( + p_chunk=p_chunk, + arrays=arrays, + disease_ids=chunk.tolist(), + sex_value=sex_value, + sex_name=sex_name, + age_groups=age_groups, + offset=float(offset), + valid_target_min_id=valid_target_min_id, + num_workers=num_workers_auc, + auc_task_chunk_size=auc_task_chunk_size, + ) + for r in rows: + r["disease_chunk_idx"] = int(chunk_idx) + all_rows.extend(rows) + del p_chunk + + del hidden_all, arrays + df_auc_unpooled = pd.DataFrame(all_rows) + if df_auc_unpooled.empty: + raise RuntimeError( + "No AUC rows were produced. Check offset, age_groups, eval split, and disease ids.") + + # Keep outputs self-contained with only evaluation fields and token->code mapping. + df_auc_unpooled["label_code"] = df_auc_unpooled["token"].map( + dataset.label_id_to_code) + + print("Using DeLong method to calculate AUC confidence intervals.") + grouped = df_auc_unpooled.groupby( + ["token", "label_code", "offset"], dropna=False, as_index=False) + df_auc = grouped.agg( + auc=("auc_delong", "mean"), + n_strata=("auc_delong", "size"), + n_diseased=("n_diseased", "sum"), + n_healthy=("n_healthy", "sum"), + auc_variance_sum=("auc_variance_delong", "sum"), + ) + df_auc["auc_variance_delong"] = ( + df_auc["auc_variance_sum"] + / (df_auc["n_strata"].clip(lower=1).astype(np.float64) ** 2) + ) + df_auc = df_auc.drop(columns=["auc_variance_sum"]) + + if output_path is not None: + out_dir = Path(output_path) + out_dir.mkdir(parents=True, exist_ok=True) + df_auc.to_csv(out_dir / "df_both.csv", index=False) + df_auc_unpooled.to_csv( + out_dir / "df_auc_unpooled.csv", index=False) + + return df_auc_unpooled, df_auc + + +# --------------------------------------------------------------------------- +# CLI +# --------------------------------------------------------------------------- + +def parse_int_list(s: Any) -> Optional[List[int]]: + if s is None: + return None + if isinstance(s, (list, tuple, np.ndarray)): + return [int(x) for x in s] + text = str(s).strip() + if text == "": + return None + if text.startswith("["): + try: + values = json.loads(text) + except json.JSONDecodeError as exc: + raise ValueError(f"Invalid integer list: {text!r}") from exc + if not isinstance(values, list): + raise ValueError(f"Expected a JSON list, got {type(values).__name__}") + return [int(x) for x in values] + return [int(x.strip()) for x in text.split(",") if x.strip()] + + +def parse_float_list(s: Any) -> Optional[List[float]]: + if s is None: + return None + if isinstance(s, (list, tuple, np.ndarray)): + return [float(x) for x in s] + text = str(s).strip() + if text == "": + return None + if text.startswith("["): + try: + values = json.loads(text) + except json.JSONDecodeError as exc: + raise ValueError(f"Invalid float list: {text!r}") from exc + if not isinstance(values, list): + raise ValueError(f"Expected a JSON list, got {type(values).__name__}") + return [float(x) for x in values] + return [float(x.strip()) for x in text.split(",") if x.strip()] + + +def make_auc_offsets(args: argparse.Namespace, cfg: Dict[str, Any]) -> List[float]: + explicit_offsets = parse_float_list(cfg_get(args, cfg, "offsets", None)) + if explicit_offsets is not None: + base_offsets = explicit_offsets + else: + next_token_offset = float(cfg_get(args, cfg, "offset", 0.1)) + base_offsets = [next_token_offset, 1.0, 5.0, 10.0] + + offsets: List[float] = [] + seen = set() + for value in base_offsets: + value = float(value) + key = round(value, 10) + if key not in seen: + offsets.append(value) + seen.add(key) + if not offsets: + raise ValueError("At least one AUC offset is required.") + return offsets + + +def main() -> None: + parser = argparse.ArgumentParser(description="Evaluate DeepHealth AUC") + + # Simplify arguments to only include run_path and output_path + parser.add_argument("--run_path", type=str, required=True, + help="Path containing train_config.json and best_model.pt") + parser.add_argument("--output_path", type=str, + default=None, help="Defaults to run_path") + parser.add_argument("--eval_split", type=str, default=None, + choices=["train", "val", "valid", + "validation", "test", "all"], + help="Evaluation split. Defaults to 'test' unless cfg contains eval_split.") + parser.add_argument("--dataset_subset_size", type=int, default=None, + help="Optional number of patients from the selected split.") + parser.add_argument("--batch_size", type=int, default=None, + help="Inference batch size; overrides train_config.json.") + parser.add_argument("--num_workers", type=int, default=None, + help="DataLoader workers; overrides train_config.json.") + parser.add_argument("--device", type=str, default=None, + help="Evaluation device, e.g. cpu, cuda, cuda:1. Defaults to cuda if available, else cpu.") + parser.add_argument("--num_workers_auc", type=int, default=None, + help="CPU processes for AUC computation.") + parser.add_argument("--auc_task_chunk_size", type=int, default=None, + help="Diseases per submitted CPU task block. 0/None auto-tunes.") + parser.add_argument("--hidden_cache_dtype", type=str, default=None, choices=["float16", "float32"], + help="CPU dtype for cached readout hidden states. float16 saves memory and is usually enough for AUC.") + parser.add_argument("--logit_batch_size", type=int, default=None, + help="Patient batch size for projecting cached hidden states to disease logits.") + parser.add_argument("--disease_chunk_size", type=int, default=None, + help="Number of disease logits to materialize per inference pass. <=0 means one chunk (all diseases).") + parser.add_argument("--filter_min_total", type=int, default=None, + help="Minimum metadata count for disease selection; default 0.") + parser.add_argument("--offset", type=float, default=None, + help="Next-token prediction offset in years; preserved and evaluated alongside 1, 5, and 10 years by default.") + parser.add_argument("--offsets", type=str, default=None, + help="Comma-separated prediction offsets in years. Overrides the default set of offset,1,5,10.") + parser.add_argument("--age_start", type=float, default=None) + parser.add_argument("--age_stop", type=float, default=None) + parser.add_argument("--age_step", type=float, default=None) + parser.add_argument("--use_amp", action=argparse.BooleanOptionalAction, default=None, + help="Use CUDA autocast during inference.") + + args = parser.parse_args() + + # Extract paths from run_path + run_path = Path(args.run_path) + config_path = run_path / "train_config.json" + model_ckpt_path = run_path / "best_model.pt" + + if not config_path.exists(): + raise FileNotFoundError(f"train_config.json not found in {run_path}") + if not model_ckpt_path.exists(): + raise FileNotFoundError(f"best_model.pt not found in {run_path}") + + cfg = load_json_config(str(config_path)) + + if args.output_path is None: + args.output_path = str(run_path) + + # Load configurations from train_config.json + data_prefix = cfg.get("data_prefix", "ukb") + labels_file = cfg.get("labels_file", "labels.csv") + no_event_interval_years = cfg.get("no_event_interval_years", 5.0) + include_no_event = cfg.get("include_no_event_in_uts_target", False) + + target_mode = cfg.get("target_mode", "uts") + model_target_mode = str(cfg.get("model_target_mode", "next_token")).lower() + if model_target_mode not in {"next_token", "all_future"}: + raise ValueError( + "train_config.json model_target_mode must be next_token or all_future, " + f"got {model_target_mode!r}" + ) + dist_mode_cfg = cfg.get("dist_mode", "exponential") + readout_name = cfg.get( + "readout_name", "same_time_group_end" if target_mode == "uts" else "token") + readout_reduce = cfg.get("readout_reduce", "mean") + + device = resolve_eval_device(args.device) + if device.type == "cuda": + torch.backends.cudnn.benchmark = True + + print("Loading dataset...") + dataset = load_sequence_eval_dataset( + model_target_mode=model_target_mode, + data_prefix=data_prefix, + labels_file=labels_file, + no_event_interval_years=no_event_interval_years, + include_no_event_in_uts_target=include_no_event, + min_history_events=int(cfg.get("all_future_min_history_events", 1)), + min_future_events=int(cfg.get("all_future_min_future_events", 1)), + extra_info_types=parse_int_list(cfg.get("extra_info_types", None)), + ) + validate_dataset_metadata(dataset, cfg) + + subset, subset_indices = make_eval_subset(dataset, args, cfg) + print(f"Dataset: {len(dataset)} samples, vocab_size={dataset.vocab_size}") + + loader = DataLoader( + subset, + batch_size=int(cfg_get(args, cfg, "batch_size", 128)), + shuffle=False, + collate_fn=sequence_eval_collate_fn, + num_workers=int(cfg_get(args, cfg, "num_workers", 4)), + pin_memory=device.type == "cuda", + persistent_workers=int(cfg_get(args, cfg, "num_workers", 4)) > 0, + prefetch_factor=2 if int( + cfg_get(args, cfg, "num_workers", 4)) > 0 else None, + ) + + print("Building/loading model...") + state_dict = load_checkpoint_state_dict( + str(model_ckpt_path), map_location="cpu") + dist_mode = resolve_dist_mode_for_checkpoint(dist_mode_cfg, state_dict) + cfg = dict(cfg) + cfg["dist_mode"] = dist_mode + cfg["model_target_mode"] = model_target_mode + print(f"Resolved dist_mode for evaluation: {dist_mode}") + print(f"Model target mode for AUC: {model_target_mode}") + print( + "AUC score semantics: evaluate_auc.py uses disease-specific eta/logit scores; " + "dist_mode affects model loading but is not converted to horizon-specific risk probability." + ) + + model = build_model_from_dataset(args, cfg, dataset).to(device) + load_model_state(model, str(model_ckpt_path), + device, state_dict=state_dict) + model.eval() + + age_groups = np.arange( + float(cfg_get(args, cfg, "age_start", 40.0)), + float(cfg_get(args, cfg, "age_stop", 80.0)), + float(cfg_get(args, cfg, "age_step", 5.0)), + dtype=np.float32, + ) + disease_spec = cfg_get(args, cfg, "diseases_of_interest", None) + if disease_spec is None: + disease_spec = cfg.get("disease_tokens", None) + diseases = parse_int_list(disease_spec) + first_occurrence_by_token, _, _, _ = _build_first_occurrence_maps( + dataset, subset_indices) + include_death = bool(cfg_get(args, cfg, "include_death", True)) + exclude_death = bool(cfg_get(args, cfg, "exclude_death", False)) + auc_offsets = make_auc_offsets(args, cfg) + + evaluate_auc_pipeline( + model=model, + loader=loader, + dataset=dataset, + output_path=args.output_path, + diseases_of_interest=diseases, + filter_min_total=int(cfg_get(args, cfg, "filter_min_total", 0)), + first_occurrence_by_token=first_occurrence_by_token, + include_death=include_death, + exclude_death=exclude_death, + disease_chunk_size=int(cfg_get(args, cfg, "disease_chunk_size", 0)), + age_groups=age_groups, + offsets=auc_offsets, + device=device, + model_target_mode=model_target_mode, + readout_name=readout_name, + readout_reduce=readout_reduce, + num_workers_auc=int(cfg_get(args, cfg, "num_workers_auc", max( + 1, (os.cpu_count() or 2) - 1))), + use_amp=bool(cfg_get(args, cfg, "use_amp", False)), + auc_task_chunk_size=int(cfg_get(args, cfg, "auc_task_chunk_size", 0)), + hidden_cache_dtype=str( + cfg_get(args, cfg, "hidden_cache_dtype", "float16")), + logit_batch_size=int( + cfg_get(args, cfg, "logit_batch_size", cfg_get(args, cfg, "batch_size", 128))), + ) + + +if __name__ == "__main__": + main() diff --git a/evaluate_token_auc.py b/evaluate_token_auc.py new file mode 100644 index 0000000..17d6330 --- /dev/null +++ b/evaluate_token_auc.py @@ -0,0 +1,7 @@ +from __future__ import annotations + +from evaluate_auc import main + + +if __name__ == "__main__": + main() diff --git a/event_date_utils.py b/event_date_utils.py new file mode 100644 index 0000000..24e602e --- /dev/null +++ b/event_date_utils.py @@ -0,0 +1,104 @@ +"""Read and query calendar-dated disease-event arrays from prepare_event_dates.py.""" + +from __future__ import annotations + +from dataclasses import dataclass +from pathlib import Path +from typing import Iterable + +import numpy as np +import pandas as pd + + +REQUIRED_FIELDS = {"eid", "event_date", "token"} + + +def load_event_dates(path: str | Path) -> np.ndarray: + """Load and validate the structured ``.npy`` event array.""" + events = np.load(path) + if events.dtype.names is None or not REQUIRED_FIELDS.issubset(events.dtype.names): + raise ValueError( + "Expected a structured .npy with eid, event_date, token fields. " + "Create it with prepare_event_dates.py." + ) + return events + + +def load_token_labels(labels_file: str | Path) -> dict[int, str]: + """Load token -> human-readable code using the project label convention.""" + labels = {1: "CHECKUP"} + with Path(labels_file).open(encoding="utf-8") as handle: + for index, line in enumerate(handle): + code = line.strip().split(" ", maxsplit=1)[0] + if code: + labels[index + 2] = code + return labels + + +@dataclass +class EventDateIndex: + """Small in-memory query wrapper for exposure-linkage and cohort scripts.""" + + events: np.ndarray + token_labels: dict[int, str] | None = None + + @classmethod + def from_files( + cls, + event_file: str | Path, + labels_file: str | Path | None = None, + ) -> "EventDateIndex": + labels = load_token_labels(labels_file) if labels_file is not None else None + return cls(load_event_dates(event_file), labels) + + def to_frame(self, events: np.ndarray | None = None) -> pd.DataFrame: + """Convert records to a convenient, calendar-dated DataFrame.""" + data = self.events if events is None else events + frame = pd.DataFrame( + { + "eid": data["eid"].astype("int64"), + "event_date": pd.to_datetime(data["event_date"]), + "token": data["token"].astype("int32"), + } + ) + if self.token_labels is not None: + frame["label_code"] = frame["token"].map(self.token_labels).fillna("UNKNOWN") + return frame.sort_values(["eid", "event_date", "token"], kind="stable").reset_index(drop=True) + + def for_eid(self, eid: int) -> pd.DataFrame: + """Return every stored disease/death event for one participant.""" + return self.to_frame(self.events[self.events["eid"] == int(eid)]) + + def between( + self, + start: str | pd.Timestamp, + end: str | pd.Timestamp, + *, + eids: Iterable[int] | None = None, + tokens: Iterable[int] | None = None, + ) -> pd.DataFrame: + """Query events in an inclusive calendar-date interval.""" + start_day = np.datetime64(pd.Timestamp(start).date(), "D") + end_day = np.datetime64(pd.Timestamp(end).date(), "D") + mask = (self.events["event_date"] >= start_day) & (self.events["event_date"] <= end_day) + if eids is not None: + mask &= np.isin(self.events["eid"], list(eids)) + if tokens is not None: + mask &= np.isin(self.events["token"], list(tokens)) + return self.to_frame(self.events[mask]) + + def anchors_before(self, eid: int, date: str | pd.Timestamp) -> pd.DataFrame: + """Return a participant's event history strictly before an exposure anchor.""" + day = np.datetime64(pd.Timestamp(date).date(), "D") + mask = (self.events["eid"] == int(eid)) & (self.events["event_date"] < day) + return self.to_frame(self.events[mask]) + + def first_event(self, token: int) -> pd.DataFrame: + """Return each participant's first date for a requested token.""" + selected = self.events[self.events["token"] == int(token)] + # Arrays produced by prepare_event_dates.py are already deduplicated; + # sorting makes this safe for externally produced compatible arrays too. + order = np.lexsort((selected["event_date"], selected["eid"])) + selected = selected[order] + _, first = np.unique(selected["eid"], return_index=True) + return self.to_frame(selected[first]) diff --git a/extra_info_types_all.txt b/extra_info_types_all.txt new file mode 100644 index 0000000..076e0b8 --- /dev/null +++ b/extra_info_types_all.txt @@ -0,0 +1,268 @@ +# All other-info variables (field_type=1 and field_type=2) +# Generated from field_ids_enriched.csv using prepare_data.py other-info type ordering. +# Format: # | +1 # waist_circumference | Waist circumference +2 # hip_circumference | Hip circumference +3 # standing_height | Standing height +4 # fasting_time | Fasting time +5 # pulse_rate | Pulse rate automated reading +6 # dbp | Diastolic blood pressure automated reading +7 # sbp | Systolic blood pressure automated reading +8 # fev1_best | Forced expiratory volume in 1-second (FEV1) Best measure +9 # fvc_best | Forced vital capacity (FVC) Best measure +10 # fev1_fvc_ratio | FEV1/ FVC ratio Z-score +11 # bmi | Body mass index (BMI) +12 # WBC | White blood cell (leukocyte) count +13 # RBC | Red blood cell (erythrocyte) count +14 # hemoglobin | Haemoglobin concentration +15 # hematocrit | Haematocrit percentage +16 # MCV | Mean corpuscular volume +17 # MCH | Mean corpuscular haemoglobin +18 # MCHC | Mean corpuscular haemoglobin concentration +19 # Pc | Platelet count +20 # MPV | Mean platelet (thrombocyte) volume +21 # LymC | Lymphocyte count +22 # MonC | Monocyte count +23 # NeuC | Neutrophill count +24 # EosC | Eosinophill count +25 # BasC | Basophill count +26 # nRBC | Nucleated red blood cell count +27 # RC | Reticulocyte count +28 # MRV | Mean reticulocyte volume +29 # MSCV | Mean sphered cell volume +30 # IRF | Immature reticulocyte fraction +31 # HLSRC | High light scatter reticulocyte count +32 # MicU | Microalbumin in urine +33 # CreaU | Creatinine (enzymatic) in urine +34 # PotU | Potassium in urine +35 # SodU | Sodium in urine +36 # Alb | Albumin +37 # ALP | Alkaline phosphatase +38 # Alanine | Alanine aminotransferase +39 # ApoA | Apolipoprotein A +40 # ApoB | Apolipoprotein B +41 # AA | Aspartate aminotransferase +42 # DBil | Direct bilirubin +43 # Urea | Urea +44 # Calcium | Calcium +45 # Cholesterol | Cholesterol +46 # Creatinine | Creatinine +47 # CRP | C-reactive protein +48 # CystatinC | Cystatin C +49 # GGT | Gamma glutamyltransferase +50 # Glu | Glucose +51 # HbA1c | Glycated haemoglobin (HbA1c) +52 # HDL | HDL cholesterol +53 # IGF1 | IGF-1 +54 # LDL | LDL direct +55 # LpA | Lipoprotein A +56 # Oestradiol | Oestradiol +57 # Phosphate | Phosphate +58 # Rheu | Rheumatoid factor +59 # SHBG | SHBG +60 # TotalBil | Total bilirubin +61 # Testosterone | Testosterone +62 # TotalProtein | Total protein +63 # Tri | Triglycerides +64 # Urate | Urate +65 # VitaminD | Vitamin D +66 # smoking | Current tobacco smoking +67 # alcohol | Alcohol intake frequency. +68 # ipaq_activity_group | IPAQ activity group +69 # moderate_activity_met_minutes_week | MET minutes per week for moderate activity +70 # vigorous_activity_met_minutes_week | MET minutes per week for vigorous activity +71 # walking_met_minutes_week | MET minutes per week for walking +72 # total_activity_met_minutes_week | Summed MET minutes per week for all activity +73 # total_activity_days | Summed days activity +74 # total_activity_minutes | Summed minutes activity +75 # heavy_diy_duration | Duration of heavy DIY +76 # light_diy_duration | Duration of light DIY +77 # moderate_activity_duration | Duration of moderate activity +78 # other_exercise_duration | Duration of other exercises +79 # strenuous_sport_duration | Duration of strenuous sports +80 # vigorous_activity_duration | Duration of vigorous activity +81 # walking_duration | Duration of walks +82 # pleasure_walking_duration | Duration walking for pleasure +83 # heavy_diy_frequency_4_weeks | Frequency of heavy DIY in last 4 weeks +84 # light_diy_frequency_4_weeks | Frequency of light DIY in last 4 weeks +85 # other_exercise_frequency_4_weeks | Frequency of other exercises in last 4 weeks +86 # stair_climbing_frequency_4_weeks | Frequency of stair climbing in last 4 weeks +87 # strenuous_sport_frequency_4_weeks | Frequency of strenuous sports in last 4 weeks +88 # pleasure_walking_frequency_4_weeks | Frequency of walking for pleasure in last 4 weeks +89 # moderate_activity_days_week_10min | Number of days/week of moderate physical activity 10+ minutes +90 # vigorous_activity_days_week_10min | Number of days/week of vigorous physical activity 10+ minutes +91 # walking_days_week_10min | Number of days/week walked 10+ minutes +92 # driving_time | Time spent driving +93 # computer_use_time | Time spent using computer +94 # tv_watching_time | Time spent watching television (TV) +95 # physical_activity_types_4_weeks | Types of physical activity in last 4 weeks +96 # nonwork_transport_types | Types of transport used (excluding work) +97 # usual_walking_pace | Usual walking pace +98 # mobile_phone_use_duration | Length of mobile phone use +99 # mobile_phone_use_weekly_3_months | Weekly usage of mobile phone in last 3 months +100 # computer_game_playing | Plays computer games +101 # sleep_duration | Sleep duration +102 # chronotype | Morning/evening person (chronotype) +103 # daytime_napping | Nap during day +104 # insomnia | Sleeplessness / insomnia +105 # daytime_dozing | Daytime dozing / sleeping +106 # ever_smoked | Ever smoked +107 # smoking_pack_years | Pack years of smoking +108 # smoking_status | Smoking status +109 # past_tobacco_smoking | Past tobacco smoking +110 # lifetime_smoking_100_plus | Light smokers, at least 100 smokes in lifetime +111 # current_tobacco_type | Type of tobacco currently smoked +112 # current_cigarettes_per_day | Number of cigarettes currently smoked daily (current cigarette smokers) +113 # previous_cigarettes_per_day_current_cigar_pipe_smokers | Number of cigarettes previously smoked daily (current cigar/pipe smokers) +114 # time_to_first_cigarette | Time from waking to first cigarette +115 # ever_tried_smoking_cessation | Ever tried to stop smoking +116 # smoking_change_vs_10_years_ago | Smoking compared to 10 years previous +117 # previous_tobacco_type | Type of tobacco previously smoked +118 # previous_cigarettes_per_day | Number of cigarettes previously smoked daily +119 # ever_stopped_smoking_6_months | Ever stopped smoking for 6+ months +120 # household_smokers | Smoking/smokers in household +121 # home_secondhand_smoke_exposure | Exposure to tobacco smoke at home +122 # nonhome_secondhand_smoke_exposure | Exposure to tobacco smoke outside home +123 # cooked_vegetable_intake | Cooked vegetable intake +124 # raw_vegetable_intake | Salad / raw vegetable intake +125 # fresh_fruit_intake | Fresh fruit intake +126 # dried_fruit_intake | Dried fruit intake +127 # oily_fish_intake | Oily fish intake +128 # non_oily_fish_intake | Non-oily fish intake +129 # processed_meat_intake | Processed meat intake +130 # poultry_intake | Poultry intake +131 # beef_intake | Beef intake +132 # lamb_mutton_intake | Lamb/mutton intake +133 # pork_intake | Pork intake +134 # age_last_ate_meat | Age when last ate meat +135 # food_avoidance_eggs_dairy_wheat_sugar | Never eat eggs, dairy, wheat, sugar +136 # cheese_intake | Cheese intake +137 # milk_type | Milk type used +138 # spread_type | Spread type +139 # bread_intake | Bread intake +140 # bread_type | Bread type +141 # cereal_intake | Cereal intake +142 # cereal_type | Cereal type +143 # added_salt | Salt added to food +144 # tea_intake | Tea intake +145 # coffee_intake | Coffee intake +146 # coffee_type | Coffee type +147 # hot_drink_temperature | Hot drink temperature +148 # water_intake | Water intake +149 # diet_variation | Variation in diet +150 # alcohol_drinker_status | Alcohol drinker status +151 # former_alcohol_drinker | Former alcohol drinker +152 # red_wine_intake_monthly | Average monthly red wine intake +153 # champagne_white_wine_intake_monthly | Average monthly champagne plus white wine intake +154 # beer_cider_intake_monthly | Average monthly beer plus cider intake +155 # spirits_intake_monthly | Average monthly spirits intake +156 # fortified_wine_intake_monthly | Average monthly fortified wine intake +157 # other_alcohol_intake_monthly | Average monthly intake of other alcoholic drinks +158 # red_wine_intake_weekly | Average weekly red wine intake +159 # champagne_white_wine_intake_weekly | Average weekly champagne plus white wine intake +160 # beer_cider_intake_weekly | Average weekly beer plus cider intake +161 # spirits_intake_weekly | Average weekly spirits intake +162 # fortified_wine_intake_weekly | Average weekly fortified wine intake +163 # other_alcohol_intake_weekly | Average weekly intake of other alcoholic drinks +164 # alcohol_with_meals | Alcohol usually taken with meals +165 # country_of_birth_uk_elsewhere | Country of birth (UK/elsewhere) +166 # breastfed_in_infancy | Breastfed as a baby +167 # comparative_body_size_age_10 | Comparative body size at age 10 +168 # comparative_height_age_10 | Comparative height size at age 10 +169 # handedness | Handedness (chirality/laterality) +170 # adopted_as_child | Adopted as a child +171 # multiple_birth | Part of a multiple birth +172 # maternal_smoking_around_birth | Maternal smoking around birth +173 # accommodation_type | Type of accommodation lived in +174 # housing_tenure | Own or rent accommodation lived in +175 # gas_solid_fuel_use | Gas or solid-fuel cooking/heating +176 # home_heating_types | Heating type(s) in home +177 # household_vehicle_count | Number of vehicles in household +178 # household_income_before_tax | Average total household income before tax +179 # current_employment_status | Current employment status +180 # current_employment_status_corrected | Current employment status - corrected +181 # home_work_distance | Distance between home and job workplace +182 # main_job_hours_week | Length of working week for main job +183 # commuting_frequency | Frequency of travelling from home to job workplace +184 # commuting_transport_type | Transport type for commuting to job workplace +185 # job_walking_standing | Job involves mainly walking or standing +186 # job_heavy_manual_work | Job involves heavy manual or physical work +187 # job_shift_work | Job involves shift work +188 # job_night_shift_work | Job involves night shift work +189 # educational_qualifications | Qualifications +190 # age_completed_full_time_education | Age completed full time education +191 # friend_family_visit_frequency | Frequency of friend/family visits +192 # leisure_social_activities | Leisure/social activities +193 # ability_to_confide | Able to confide +194 # bipolar_major_depression_status | Bipolar and major depression status +195 # neuroticism_score | Neuroticism score +196 # mood_swings | Mood swings +197 # miserableness | Miserableness +198 # irritability | Irritability +199 # sensitivity_hurt_feelings | Sensitivity / hurt feelings +200 # fed_up_feelings | Fed-up feelings +201 # nervous_feelings | Nervous feelings +202 # worry_anxiety_feelings | Worrier / anxious feelings +203 # tenseness_highly_strung | Tense / 'highly strung' +204 # suffering_from_nerves | Suffer from 'nerves' +205 # loneliness_isolation | Loneliness, isolation +206 # guilty_feelings | Guilty feelings +207 # risk_taking | Risk taking +208 # happiness | Happiness +209 # job_satisfaction | Work/job satisfaction +210 # health_satisfaction | Health satisfaction +211 # family_relationship_satisfaction | Family relationship satisfaction +212 # friendship_satisfaction | Friendships satisfaction +213 # financial_situation_satisfaction | Financial situation satisfaction +214 # depressed_mood_frequency_2_weeks | Frequency of depressed mood in last 2 weeks +215 # disinterest_frequency_2_weeks | Frequency of unenthusiasm / disinterest in last 2 weeks +216 # tenseness_restlessness_frequency_2_weeks | Frequency of tenseness / restlessness in last 2 weeks +217 # tiredness_lethargy_frequency_2_weeks | Frequency of tiredness / lethargy in last 2 weeks +218 # ever_depressed_full_week | Ever depressed for a whole week +219 # longest_depression_duration | Longest period of depression +220 # depression_episode_count | Number of depression episodes +221 # longest_disinterest_duration | Longest period of unenthusiasm / disinterest +222 # disinterest_episode_count | Number of unenthusiastic/disinterested episodes +223 # ever_manic_hyper_2_days | Ever manic/hyper for 2 days +224 # ever_irritable_argumentative_2_days | Ever highly irritable/argumentative for 2 days +225 # manic_hyper_symptoms | Manic/hyper symptoms +226 # longest_manic_irritable_episode_duration | Length of longest manic/irritable episode +227 # manic_irritable_episode_severity | Severity of manic/irritable episodes +228 # adverse_life_events_2_years | Illness, injury, bereavement, stress in last 2 years +229 # outdoor_time_summer | Time spend outdoors in summer +230 # outdoor_time_winter | Time spent outdoors in winter +231 # skin_tanning_ease | Ease of skin tanning +232 # childhood_sunburn_frequency | Childhood sunburn occasions +233 # sun_uv_protection_use | Use of sun/uv protection +234 # solarium_sunlamp_frequency | Frequency of solarium/sunlamp use +235 # proximity_to_major_road | Close to major road +236 # inverse_distance_nearest_major_road | Inverse distance to the nearest major road +237 # inverse_distance_nearest_road | Inverse distance to the nearest road +238 # no2_2005 | Nitrogen dioxide air pollution; 2005 +239 # no2_2006 | Nitrogen dioxide air pollution; 2006 +240 # no2_2007 | Nitrogen dioxide air pollution; 2007 +241 # no2_2010 | Nitrogen dioxide air pollution; 2010 +242 # nox_2010 | Nitrogen oxides air pollution; 2010 +243 # pm10_2007 | Particulate matter air pollution (pm10); 2007 +244 # pm10_2010 | Particulate matter air pollution (pm10); 2010 +245 # pm25_absorbance_2010 | Particulate matter air pollution (pm2.5) absorbance; 2010 +246 # pm25_2010 | Particulate matter air pollution (pm2.5); 2010 +247 # pm25_10_2010 | Particulate matter air pollution 2.5-10um; 2010 +248 # major_road_length_100m | Sum of road length of major roads within 100m +249 # major_road_traffic_load | Total traffic load on major roads +250 # nearest_major_road_traffic_intensity | Traffic intensity on the nearest major road +251 # nearest_road_traffic_intensity | Traffic intensity on the nearest road +252 # noise_level_16h | Average 16-hour sound level of noise pollution +253 # noise_level_24h | Average 24-hour sound level of noise pollution +254 # noise_level_daytime | Average daytime sound level of noise pollution +255 # noise_level_evening | Average evening sound level of noise pollution +256 # noise_level_nighttime | Average night-time sound level of noise pollution +257 # natural_environment_percent_1000m | Natural environment percentage, buffer 1000m +258 # natural_environment_percent_300m | Natural environment percentage, buffer 300m +259 # greenspace_percent_1000m | Greenspace percentage, buffer 1000m +260 # greenspace_percent_300m | Greenspace percentage, buffer 300m +261 # domestic_garden_percent_1000m | Domestic garden percentage, buffer 1000m +262 # domestic_garden_percent_300m | Domestic garden percentage, buffer 300m +263 # water_percent_1000m | Water percentage, buffer 1000m +264 # water_percent_300m | Water percentage, buffer 300m +265 # distance_to_coast | Distance (Euclidean) to coast diff --git a/extra_info_types_assessment_only.txt b/extra_info_types_assessment_only.txt new file mode 100644 index 0000000..7535941 --- /dev/null +++ b/extra_info_types_assessment_only.txt @@ -0,0 +1,68 @@ +# Only assessment/body-measurement variables (field_type=1) +# Generated from field_ids_enriched.csv using prepare_data.py other-info type ordering. +# Format: # | +1 # waist_circumference | Waist circumference +2 # hip_circumference | Hip circumference +3 # standing_height | Standing height +4 # fasting_time | Fasting time +5 # pulse_rate | Pulse rate automated reading +6 # dbp | Diastolic blood pressure automated reading +7 # sbp | Systolic blood pressure automated reading +8 # fev1_best | Forced expiratory volume in 1-second (FEV1) Best measure +9 # fvc_best | Forced vital capacity (FVC) Best measure +10 # fev1_fvc_ratio | FEV1/ FVC ratio Z-score +11 # bmi | Body mass index (BMI) +12 # WBC | White blood cell (leukocyte) count +13 # RBC | Red blood cell (erythrocyte) count +14 # hemoglobin | Haemoglobin concentration +15 # hematocrit | Haematocrit percentage +16 # MCV | Mean corpuscular volume +17 # MCH | Mean corpuscular haemoglobin +18 # MCHC | Mean corpuscular haemoglobin concentration +19 # Pc | Platelet count +20 # MPV | Mean platelet (thrombocyte) volume +21 # LymC | Lymphocyte count +22 # MonC | Monocyte count +23 # NeuC | Neutrophill count +24 # EosC | Eosinophill count +25 # BasC | Basophill count +26 # nRBC | Nucleated red blood cell count +27 # RC | Reticulocyte count +28 # MRV | Mean reticulocyte volume +29 # MSCV | Mean sphered cell volume +30 # IRF | Immature reticulocyte fraction +31 # HLSRC | High light scatter reticulocyte count +32 # MicU | Microalbumin in urine +33 # CreaU | Creatinine (enzymatic) in urine +34 # PotU | Potassium in urine +35 # SodU | Sodium in urine +36 # Alb | Albumin +37 # ALP | Alkaline phosphatase +38 # Alanine | Alanine aminotransferase +39 # ApoA | Apolipoprotein A +40 # ApoB | Apolipoprotein B +41 # AA | Aspartate aminotransferase +42 # DBil | Direct bilirubin +43 # Urea | Urea +44 # Calcium | Calcium +45 # Cholesterol | Cholesterol +46 # Creatinine | Creatinine +47 # CRP | C-reactive protein +48 # CystatinC | Cystatin C +49 # GGT | Gamma glutamyltransferase +50 # Glu | Glucose +51 # HbA1c | Glycated haemoglobin (HbA1c) +52 # HDL | HDL cholesterol +53 # IGF1 | IGF-1 +54 # LDL | LDL direct +55 # LpA | Lipoprotein A +56 # Oestradiol | Oestradiol +57 # Phosphate | Phosphate +58 # Rheu | Rheumatoid factor +59 # SHBG | SHBG +60 # TotalBil | Total bilirubin +61 # Testosterone | Testosterone +62 # TotalProtein | Total protein +63 # Tri | Triglycerides +64 # Urate | Urate +65 # VitaminD | Vitamin D diff --git a/extra_info_types_exposure_only.txt b/extra_info_types_exposure_only.txt new file mode 100644 index 0000000..0fd3f94 --- /dev/null +++ b/extra_info_types_exposure_only.txt @@ -0,0 +1,203 @@ +# Only environment/lifestyle exposure variables (field_type=2) +# Generated from field_ids_enriched.csv using prepare_data.py other-info type ordering. +# Format: # | +66 # smoking | Current tobacco smoking +67 # alcohol | Alcohol intake frequency. +68 # ipaq_activity_group | IPAQ activity group +69 # moderate_activity_met_minutes_week | MET minutes per week for moderate activity +70 # vigorous_activity_met_minutes_week | MET minutes per week for vigorous activity +71 # walking_met_minutes_week | MET minutes per week for walking +72 # total_activity_met_minutes_week | Summed MET minutes per week for all activity +73 # total_activity_days | Summed days activity +74 # total_activity_minutes | Summed minutes activity +75 # heavy_diy_duration | Duration of heavy DIY +76 # light_diy_duration | Duration of light DIY +77 # moderate_activity_duration | Duration of moderate activity +78 # other_exercise_duration | Duration of other exercises +79 # strenuous_sport_duration | Duration of strenuous sports +80 # vigorous_activity_duration | Duration of vigorous activity +81 # walking_duration | Duration of walks +82 # pleasure_walking_duration | Duration walking for pleasure +83 # heavy_diy_frequency_4_weeks | Frequency of heavy DIY in last 4 weeks +84 # light_diy_frequency_4_weeks | Frequency of light DIY in last 4 weeks +85 # other_exercise_frequency_4_weeks | Frequency of other exercises in last 4 weeks +86 # stair_climbing_frequency_4_weeks | Frequency of stair climbing in last 4 weeks +87 # strenuous_sport_frequency_4_weeks | Frequency of strenuous sports in last 4 weeks +88 # pleasure_walking_frequency_4_weeks | Frequency of walking for pleasure in last 4 weeks +89 # moderate_activity_days_week_10min | Number of days/week of moderate physical activity 10+ minutes +90 # vigorous_activity_days_week_10min | Number of days/week of vigorous physical activity 10+ minutes +91 # walking_days_week_10min | Number of days/week walked 10+ minutes +92 # driving_time | Time spent driving +93 # computer_use_time | Time spent using computer +94 # tv_watching_time | Time spent watching television (TV) +95 # physical_activity_types_4_weeks | Types of physical activity in last 4 weeks +96 # nonwork_transport_types | Types of transport used (excluding work) +97 # usual_walking_pace | Usual walking pace +98 # mobile_phone_use_duration | Length of mobile phone use +99 # mobile_phone_use_weekly_3_months | Weekly usage of mobile phone in last 3 months +100 # computer_game_playing | Plays computer games +101 # sleep_duration | Sleep duration +102 # chronotype | Morning/evening person (chronotype) +103 # daytime_napping | Nap during day +104 # insomnia | Sleeplessness / insomnia +105 # daytime_dozing | Daytime dozing / sleeping +106 # ever_smoked | Ever smoked +107 # smoking_pack_years | Pack years of smoking +108 # smoking_status | Smoking status +109 # past_tobacco_smoking | Past tobacco smoking +110 # lifetime_smoking_100_plus | Light smokers, at least 100 smokes in lifetime +111 # current_tobacco_type | Type of tobacco currently smoked +112 # current_cigarettes_per_day | Number of cigarettes currently smoked daily (current cigarette smokers) +113 # previous_cigarettes_per_day_current_cigar_pipe_smokers | Number of cigarettes previously smoked daily (current cigar/pipe smokers) +114 # time_to_first_cigarette | Time from waking to first cigarette +115 # ever_tried_smoking_cessation | Ever tried to stop smoking +116 # smoking_change_vs_10_years_ago | Smoking compared to 10 years previous +117 # previous_tobacco_type | Type of tobacco previously smoked +118 # previous_cigarettes_per_day | Number of cigarettes previously smoked daily +119 # ever_stopped_smoking_6_months | Ever stopped smoking for 6+ months +120 # household_smokers | Smoking/smokers in household +121 # home_secondhand_smoke_exposure | Exposure to tobacco smoke at home +122 # nonhome_secondhand_smoke_exposure | Exposure to tobacco smoke outside home +123 # cooked_vegetable_intake | Cooked vegetable intake +124 # raw_vegetable_intake | Salad / raw vegetable intake +125 # fresh_fruit_intake | Fresh fruit intake +126 # dried_fruit_intake | Dried fruit intake +127 # oily_fish_intake | Oily fish intake +128 # non_oily_fish_intake | Non-oily fish intake +129 # processed_meat_intake | Processed meat intake +130 # poultry_intake | Poultry intake +131 # beef_intake | Beef intake +132 # lamb_mutton_intake | Lamb/mutton intake +133 # pork_intake | Pork intake +134 # age_last_ate_meat | Age when last ate meat +135 # food_avoidance_eggs_dairy_wheat_sugar | Never eat eggs, dairy, wheat, sugar +136 # cheese_intake | Cheese intake +137 # milk_type | Milk type used +138 # spread_type | Spread type +139 # bread_intake | Bread intake +140 # bread_type | Bread type +141 # cereal_intake | Cereal intake +142 # cereal_type | Cereal type +143 # added_salt | Salt added to food +144 # tea_intake | Tea intake +145 # coffee_intake | Coffee intake +146 # coffee_type | Coffee type +147 # hot_drink_temperature | Hot drink temperature +148 # water_intake | Water intake +149 # diet_variation | Variation in diet +150 # alcohol_drinker_status | Alcohol drinker status +151 # former_alcohol_drinker | Former alcohol drinker +152 # red_wine_intake_monthly | Average monthly red wine intake +153 # champagne_white_wine_intake_monthly | Average monthly champagne plus white wine intake +154 # beer_cider_intake_monthly | Average monthly beer plus cider intake +155 # spirits_intake_monthly | Average monthly spirits intake +156 # fortified_wine_intake_monthly | Average monthly fortified wine intake +157 # other_alcohol_intake_monthly | Average monthly intake of other alcoholic drinks +158 # red_wine_intake_weekly | Average weekly red wine intake +159 # champagne_white_wine_intake_weekly | Average weekly champagne plus white wine intake +160 # beer_cider_intake_weekly | Average weekly beer plus cider intake +161 # spirits_intake_weekly | Average weekly spirits intake +162 # fortified_wine_intake_weekly | Average weekly fortified wine intake +163 # other_alcohol_intake_weekly | Average weekly intake of other alcoholic drinks +164 # alcohol_with_meals | Alcohol usually taken with meals +165 # country_of_birth_uk_elsewhere | Country of birth (UK/elsewhere) +166 # breastfed_in_infancy | Breastfed as a baby +167 # comparative_body_size_age_10 | Comparative body size at age 10 +168 # comparative_height_age_10 | Comparative height size at age 10 +169 # handedness | Handedness (chirality/laterality) +170 # adopted_as_child | Adopted as a child +171 # multiple_birth | Part of a multiple birth +172 # maternal_smoking_around_birth | Maternal smoking around birth +173 # accommodation_type | Type of accommodation lived in +174 # housing_tenure | Own or rent accommodation lived in +175 # gas_solid_fuel_use | Gas or solid-fuel cooking/heating +176 # home_heating_types | Heating type(s) in home +177 # household_vehicle_count | Number of vehicles in household +178 # household_income_before_tax | Average total household income before tax +179 # current_employment_status | Current employment status +180 # current_employment_status_corrected | Current employment status - corrected +181 # home_work_distance | Distance between home and job workplace +182 # main_job_hours_week | Length of working week for main job +183 # commuting_frequency | Frequency of travelling from home to job workplace +184 # commuting_transport_type | Transport type for commuting to job workplace +185 # job_walking_standing | Job involves mainly walking or standing +186 # job_heavy_manual_work | Job involves heavy manual or physical work +187 # job_shift_work | Job involves shift work +188 # job_night_shift_work | Job involves night shift work +189 # educational_qualifications | Qualifications +190 # age_completed_full_time_education | Age completed full time education +191 # friend_family_visit_frequency | Frequency of friend/family visits +192 # leisure_social_activities | Leisure/social activities +193 # ability_to_confide | Able to confide +194 # bipolar_major_depression_status | Bipolar and major depression status +195 # neuroticism_score | Neuroticism score +196 # mood_swings | Mood swings +197 # miserableness | Miserableness +198 # irritability | Irritability +199 # sensitivity_hurt_feelings | Sensitivity / hurt feelings +200 # fed_up_feelings | Fed-up feelings +201 # nervous_feelings | Nervous feelings +202 # worry_anxiety_feelings | Worrier / anxious feelings +203 # tenseness_highly_strung | Tense / 'highly strung' +204 # suffering_from_nerves | Suffer from 'nerves' +205 # loneliness_isolation | Loneliness, isolation +206 # guilty_feelings | Guilty feelings +207 # risk_taking | Risk taking +208 # happiness | Happiness +209 # job_satisfaction | Work/job satisfaction +210 # health_satisfaction | Health satisfaction +211 # family_relationship_satisfaction | Family relationship satisfaction +212 # friendship_satisfaction | Friendships satisfaction +213 # financial_situation_satisfaction | Financial situation satisfaction +214 # depressed_mood_frequency_2_weeks | Frequency of depressed mood in last 2 weeks +215 # disinterest_frequency_2_weeks | Frequency of unenthusiasm / disinterest in last 2 weeks +216 # tenseness_restlessness_frequency_2_weeks | Frequency of tenseness / restlessness in last 2 weeks +217 # tiredness_lethargy_frequency_2_weeks | Frequency of tiredness / lethargy in last 2 weeks +218 # ever_depressed_full_week | Ever depressed for a whole week +219 # longest_depression_duration | Longest period of depression +220 # depression_episode_count | Number of depression episodes +221 # longest_disinterest_duration | Longest period of unenthusiasm / disinterest +222 # disinterest_episode_count | Number of unenthusiastic/disinterested episodes +223 # ever_manic_hyper_2_days | Ever manic/hyper for 2 days +224 # ever_irritable_argumentative_2_days | Ever highly irritable/argumentative for 2 days +225 # manic_hyper_symptoms | Manic/hyper symptoms +226 # longest_manic_irritable_episode_duration | Length of longest manic/irritable episode +227 # manic_irritable_episode_severity | Severity of manic/irritable episodes +228 # adverse_life_events_2_years | Illness, injury, bereavement, stress in last 2 years +229 # outdoor_time_summer | Time spend outdoors in summer +230 # outdoor_time_winter | Time spent outdoors in winter +231 # skin_tanning_ease | Ease of skin tanning +232 # childhood_sunburn_frequency | Childhood sunburn occasions +233 # sun_uv_protection_use | Use of sun/uv protection +234 # solarium_sunlamp_frequency | Frequency of solarium/sunlamp use +235 # proximity_to_major_road | Close to major road +236 # inverse_distance_nearest_major_road | Inverse distance to the nearest major road +237 # inverse_distance_nearest_road | Inverse distance to the nearest road +238 # no2_2005 | Nitrogen dioxide air pollution; 2005 +239 # no2_2006 | Nitrogen dioxide air pollution; 2006 +240 # no2_2007 | Nitrogen dioxide air pollution; 2007 +241 # no2_2010 | Nitrogen dioxide air pollution; 2010 +242 # nox_2010 | Nitrogen oxides air pollution; 2010 +243 # pm10_2007 | Particulate matter air pollution (pm10); 2007 +244 # pm10_2010 | Particulate matter air pollution (pm10); 2010 +245 # pm25_absorbance_2010 | Particulate matter air pollution (pm2.5) absorbance; 2010 +246 # pm25_2010 | Particulate matter air pollution (pm2.5); 2010 +247 # pm25_10_2010 | Particulate matter air pollution 2.5-10um; 2010 +248 # major_road_length_100m | Sum of road length of major roads within 100m +249 # major_road_traffic_load | Total traffic load on major roads +250 # nearest_major_road_traffic_intensity | Traffic intensity on the nearest major road +251 # nearest_road_traffic_intensity | Traffic intensity on the nearest road +252 # noise_level_16h | Average 16-hour sound level of noise pollution +253 # noise_level_24h | Average 24-hour sound level of noise pollution +254 # noise_level_daytime | Average daytime sound level of noise pollution +255 # noise_level_evening | Average evening sound level of noise pollution +256 # noise_level_nighttime | Average night-time sound level of noise pollution +257 # natural_environment_percent_1000m | Natural environment percentage, buffer 1000m +258 # natural_environment_percent_300m | Natural environment percentage, buffer 300m +259 # greenspace_percent_1000m | Greenspace percentage, buffer 1000m +260 # greenspace_percent_300m | Greenspace percentage, buffer 300m +261 # domestic_garden_percent_1000m | Domestic garden percentage, buffer 1000m +262 # domestic_garden_percent_300m | Domestic garden percentage, buffer 300m +263 # water_percent_1000m | Water percentage, buffer 1000m +264 # water_percent_300m | Water percentage, buffer 300m +265 # distance_to_coast | Distance (Euclidean) to coast diff --git a/extra_info_types_none.txt b/extra_info_types_none.txt new file mode 100644 index 0000000..95cb9f8 --- /dev/null +++ b/extra_info_types_none.txt @@ -0,0 +1,3 @@ +# No extra-info variables. +# Use this file with --extra_info_types_file to train/evaluate with disease history only. +# Keep this file free of numeric type ids; the loader parses it as an empty list. diff --git a/extra_info_types_smoking_alcohol_bmi.txt b/extra_info_types_smoking_alcohol_bmi.txt new file mode 100644 index 0000000..67f5532 --- /dev/null +++ b/extra_info_types_smoking_alcohol_bmi.txt @@ -0,0 +1,6 @@ +# Only smoking, alcohol, and BMI variables +# Generated from field_ids_enriched.csv using prepare_data.py other-info type ordering. +# Format: # | +11 # bmi | Body mass index (BMI) +66 # smoking | Current tobacco smoking +67 # alcohol | Alcohol intake frequency. \ No newline at end of file diff --git a/field_ids_enriched.csv b/field_ids_enriched.csv new file mode 100644 index 0000000..1181169 --- /dev/null +++ b/field_ids_enriched.csv @@ -0,0 +1,2564 @@ +field_instance,full_name,var_name,field_type +31-0.0,Sex,sex,0 +34-0.0,Year of birth,year,0 +48-0.0,Waist circumference,waist_circumference,1 +49-0.0,Hip circumference,hip_circumference,1 +50-0.0,Standing height,standing_height,1 +52-0.0,Month of birth,month,0 +53-0.0,Date of attending assessment centre,date_of_assessment,0 +74-0.0,Fasting time,fasting_time,1 +102-0.0,Pulse rate automated reading,pulse_rate,1 +1239-0.0,Current tobacco smoking,smoking,2 +1558-0.0,Alcohol intake frequency.,alcohol,2 +4079-0.0,Diastolic blood pressure automated reading,dbp,1 +4080-0.0,Systolic blood pressure automated reading,sbp,1 +20150-0.0,Forced expiratory volume in 1-second (FEV1) Best measure,fev1_best,1 +20151-0.0,Forced vital capacity (FVC) Best measure,fvc_best,1 +20258-0.0,FEV1/ FVC ratio Z-score,fev1_fvc_ratio,1 +21001-0.0,Body mass index (BMI),bmi,1 +21003-0.0,Age when attended assessment centre,age_at_assessment,0 +30000-0.0,White blood cell (leukocyte) count,WBC,1 +30010-0.0,Red blood cell (erythrocyte) count,RBC,1 +30020-0.0,Haemoglobin concentration,hemoglobin,1 +30030-0.0,Haematocrit percentage,hematocrit,1 +30040-0.0,Mean corpuscular volume,MCV,1 +30050-0.0,Mean corpuscular haemoglobin,MCH,1 +30060-0.0,Mean corpuscular haemoglobin concentration,MCHC,1 +30080-0.0,Platelet count,Pc,1 +30100-0.0,Mean platelet (thrombocyte) volume,MPV,1 +30120-0.0,Lymphocyte count,LymC,1 +30130-0.0,Monocyte count,MonC,1 +30140-0.0,Neutrophill count,NeuC,1 +30150-0.0,Eosinophill count,EosC,1 +30160-0.0,Basophill count,BasC,1 +30170-0.0,Nucleated red blood cell count,nRBC,1 +30250-0.0,Reticulocyte count,RC,1 +30260-0.0,Mean reticulocyte volume,MRV,1 +30270-0.0,Mean sphered cell volume,MSCV,1 +30280-0.0,Immature reticulocyte fraction,IRF,1 +30300-0.0,High light scatter reticulocyte count,HLSRC,1 +30500-0.0,Microalbumin in urine,MicU,1 +30510-0.0,Creatinine (enzymatic) in urine,CreaU,1 +30520-0.0,Potassium in urine,PotU,1 +30530-0.0,Sodium in urine,SodU,1 +30600-0.0,Albumin,Alb,1 +30610-0.0,Alkaline phosphatase,ALP,1 +30620-0.0,Alanine aminotransferase,Alanine,1 +30630-0.0,Apolipoprotein A,ApoA,1 +30640-0.0,Apolipoprotein B,ApoB,1 +30650-0.0,Aspartate aminotransferase,AA,1 +30660-0.0,Direct bilirubin,DBil,1 +30670-0.0,Urea,Urea,1 +30680-0.0,Calcium,Calcium,1 +30690-0.0,Cholesterol,Cholesterol,1 +30700-0.0,Creatinine,Creatinine,1 +30710-0.0,C-reactive protein,CRP,1 +30720-0.0,Cystatin C,CystatinC,1 +30730-0.0,Gamma glutamyltransferase,GGT,1 +30740-0.0,Glucose,Glu,1 +30750-0.0,Glycated haemoglobin (HbA1c),HbA1c,1 +30760-0.0,HDL cholesterol,HDL,1 +30770-0.0,IGF-1,IGF1,1 +30780-0.0,LDL direct,LDL,1 +30790-0.0,Lipoprotein A,LpA,1 +30800-0.0,Oestradiol,Oestradiol,1 +30810-0.0,Phosphate,Phosphate,1 +30820-0.0,Rheumatoid factor,Rheu,1 +30830-0.0,SHBG,SHBG,1 +30840-0.0,Total bilirubin,TotalBil,1 +30850-0.0,Testosterone,Testosterone,1 +30860-0.0,Total protein,TotalProtein,1 +30870-0.0,Triglycerides,Tri,1 +30880-0.0,Urate,Urate,1 +30890-0.0,Vitamin D,VitaminD,1 +40000-0.0,Date of death,Death,0 +22032-0.0,IPAQ activity group,ipaq_activity_group,2 +22038-0.0,MET minutes per week for moderate activity,moderate_activity_met_minutes_week,2 +22039-0.0,MET minutes per week for vigorous activity,vigorous_activity_met_minutes_week,2 +22037-0.0,MET minutes per week for walking,walking_met_minutes_week,2 +22040-0.0,Summed MET minutes per week for all activity,total_activity_met_minutes_week,2 +22033-0.0,Summed days activity,total_activity_days,2 +22034-0.0,Summed minutes activity,total_activity_minutes,2 +2634-0.0,Duration of heavy DIY,heavy_diy_duration,2 +1021-0.0,Duration of light DIY,light_diy_duration,2 +894-0.0,Duration of moderate activity,moderate_activity_duration,2 +3647-0.0,Duration of other exercises,other_exercise_duration,2 +1001-0.0,Duration of strenuous sports,strenuous_sport_duration,2 +914-0.0,Duration of vigorous activity,vigorous_activity_duration,2 +874-0.0,Duration of walks,walking_duration,2 +981-0.0,Duration walking for pleasure,pleasure_walking_duration,2 +2624-0.0,Frequency of heavy DIY in last 4 weeks,heavy_diy_frequency_4_weeks,2 +1011-0.0,Frequency of light DIY in last 4 weeks,light_diy_frequency_4_weeks,2 +3637-0.0,Frequency of other exercises in last 4 weeks,other_exercise_frequency_4_weeks,2 +943-0.0,Frequency of stair climbing in last 4 weeks,stair_climbing_frequency_4_weeks,2 +991-0.0,Frequency of strenuous sports in last 4 weeks,strenuous_sport_frequency_4_weeks,2 +971-0.0,Frequency of walking for pleasure in last 4 weeks,pleasure_walking_frequency_4_weeks,2 +884-0.0,Number of days/week of moderate physical activity 10+ minutes,moderate_activity_days_week_10min,2 +904-0.0,Number of days/week of vigorous physical activity 10+ minutes,vigorous_activity_days_week_10min,2 +864-0.0,Number of days/week walked 10+ minutes,walking_days_week_10min,2 +1090-0.0,Time spent driving,driving_time,2 +1080-0.0,Time spent using computer,computer_use_time,2 +1070-0.0,Time spent watching television (TV),tv_watching_time,2 +6164-0.0,Types of physical activity in last 4 weeks,physical_activity_types_4_weeks,2 +6162-0.0,Types of transport used (excluding work),nonwork_transport_types,2 +924-0.0,Usual walking pace,usual_walking_pace,2 +1110-0.0,Length of mobile phone use,mobile_phone_use_duration,2 +1120-0.0,Weekly usage of mobile phone in last 3 months,mobile_phone_use_weekly_3_months,2 +2237-0.0,Plays computer games,computer_game_playing,2 +1160-0.0,Sleep duration,sleep_duration,2 +1180-0.0,Morning/evening person (chronotype),chronotype,2 +1190-0.0,Nap during day,daytime_napping,2 +1200-0.0,Sleeplessness / insomnia,insomnia,2 +1220-0.0,Daytime dozing / sleeping,daytime_dozing,2 +20160-0.0,Ever smoked,ever_smoked,2 +20161-0.0,Pack years of smoking,smoking_pack_years,2 +20116-0.0,Smoking status,smoking_status,2 +1249-0.0,Past tobacco smoking,past_tobacco_smoking,2 +2644-0.0,"Light smokers, at least 100 smokes in lifetime",lifetime_smoking_100_plus,2 +3446-0.0,Type of tobacco currently smoked,current_tobacco_type,2 +3456-0.0,Number of cigarettes currently smoked daily (current cigarette smokers),current_cigarettes_per_day,2 +6183-0.0,Number of cigarettes previously smoked daily (current cigar/pipe smokers),previous_cigarettes_per_day_current_cigar_pipe_smokers,2 +3466-0.0,Time from waking to first cigarette,time_to_first_cigarette,2 +3486-0.0,Ever tried to stop smoking,ever_tried_smoking_cessation,2 +3506-0.0,Smoking compared to 10 years previous,smoking_change_vs_10_years_ago,2 +2877-0.0,Type of tobacco previously smoked,previous_tobacco_type,2 +2887-0.0,Number of cigarettes previously smoked daily,previous_cigarettes_per_day,2 +2907-0.0,Ever stopped smoking for 6+ months,ever_stopped_smoking_6_months,2 +1259-0.0,Smoking/smokers in household,household_smokers,2 +1269-0.0,Exposure to tobacco smoke at home,home_secondhand_smoke_exposure,2 +1279-0.0,Exposure to tobacco smoke outside home,nonhome_secondhand_smoke_exposure,2 +1289-0.0,Cooked vegetable intake,cooked_vegetable_intake,2 +1299-0.0,Salad / raw vegetable intake,raw_vegetable_intake,2 +1309-0.0,Fresh fruit intake,fresh_fruit_intake,2 +1319-0.0,Dried fruit intake,dried_fruit_intake,2 +1329-0.0,Oily fish intake,oily_fish_intake,2 +1339-0.0,Non-oily fish intake,non_oily_fish_intake,2 +1349-0.0,Processed meat intake,processed_meat_intake,2 +1359-0.0,Poultry intake,poultry_intake,2 +1369-0.0,Beef intake,beef_intake,2 +1379-0.0,Lamb/mutton intake,lamb_mutton_intake,2 +1389-0.0,Pork intake,pork_intake,2 +3680-0.0,Age when last ate meat,age_last_ate_meat,2 +6144-0.0,"Never eat eggs, dairy, wheat, sugar",food_avoidance_eggs_dairy_wheat_sugar,2 +1408-0.0,Cheese intake,cheese_intake,2 +1418-0.0,Milk type used,milk_type,2 +1428-0.0,Spread type,spread_type,2 +1438-0.0,Bread intake,bread_intake,2 +1448-0.0,Bread type,bread_type,2 +1458-0.0,Cereal intake,cereal_intake,2 +1468-0.0,Cereal type,cereal_type,2 +1478-0.0,Salt added to food,added_salt,2 +1488-0.0,Tea intake,tea_intake,2 +1498-0.0,Coffee intake,coffee_intake,2 +1508-0.0,Coffee type,coffee_type,2 +1518-0.0,Hot drink temperature,hot_drink_temperature,2 +1528-0.0,Water intake,water_intake,2 +1548-0.0,Variation in diet,diet_variation,2 +20117-0.0,Alcohol drinker status,alcohol_drinker_status,2 +3731-0.0,Former alcohol drinker,former_alcohol_drinker,2 +4407-0.0,Average monthly red wine intake,red_wine_intake_monthly,2 +4418-0.0,Average monthly champagne plus white wine intake,champagne_white_wine_intake_monthly,2 +4429-0.0,Average monthly beer plus cider intake,beer_cider_intake_monthly,2 +4440-0.0,Average monthly spirits intake,spirits_intake_monthly,2 +4451-0.0,Average monthly fortified wine intake,fortified_wine_intake_monthly,2 +4462-0.0,Average monthly intake of other alcoholic drinks,other_alcohol_intake_monthly,2 +1568-0.0,Average weekly red wine intake,red_wine_intake_weekly,2 +1578-0.0,Average weekly champagne plus white wine intake,champagne_white_wine_intake_weekly,2 +1588-0.0,Average weekly beer plus cider intake,beer_cider_intake_weekly,2 +1598-0.0,Average weekly spirits intake,spirits_intake_weekly,2 +1608-0.0,Average weekly fortified wine intake,fortified_wine_intake_weekly,2 +5364-0.0,Average weekly intake of other alcoholic drinks,other_alcohol_intake_weekly,2 +1618-0.0,Alcohol usually taken with meals,alcohol_with_meals,2 +1647-0.0,Country of birth (UK/elsewhere),country_of_birth_uk_elsewhere,2 +1677-0.0,Breastfed as a baby,breastfed_in_infancy,2 +1687-0.0,Comparative body size at age 10,comparative_body_size_age_10,2 +1697-0.0,Comparative height size at age 10,comparative_height_age_10,2 +1707-0.0,Handedness (chirality/laterality),handedness,2 +1767-0.0,Adopted as a child,adopted_as_child,2 +1777-0.0,Part of a multiple birth,multiple_birth,2 +1787-0.0,Maternal smoking around birth,maternal_smoking_around_birth,2 +670-0.0, Type of accommodation lived in,accommodation_type,2 +680-0.0, Own or rent accommodation lived in,housing_tenure,2 +6139-0.0, Gas or solid-fuel cooking/heating,gas_solid_fuel_use,2 +6140-0.0, Heating type(s) in home,home_heating_types,2 +728-0.0, Number of vehicles in household,household_vehicle_count,2 +738-0.0, Average total household income before tax,household_income_before_tax,2 +6142-0.0,Current employment status,current_employment_status,2 +20119-0.0, Current employment status - corrected,current_employment_status_corrected,2 +796-0.0,Distance between home and job workplace,home_work_distance,2 +767-0.0,Length of working week for main job,main_job_hours_week,2 +777-0.0, Frequency of travelling from home to job workplace,commuting_frequency,2 +6143-0.0, Transport type for commuting to job workplace,commuting_transport_type,2 +806-0.0, Job involves mainly walking or standing,job_walking_standing,2 +816-0.0, Job involves heavy manual or physical work,job_heavy_manual_work,2 +826-0.0, Job involves shift work,job_shift_work,2 +3426-0.0, Job involves night shift work,job_night_shift_work,2 +6138-0.0,Qualifications,educational_qualifications,2 +845-0.0,Age completed full time education,age_completed_full_time_education,2 +1031-0.0,Frequency of friend/family visits,friend_family_visit_frequency,2 +6160-0.0,Leisure/social activities,leisure_social_activities,2 +2110-0.0,Able to confide,ability_to_confide,2 +20126-0.0,Bipolar and major depression status,bipolar_major_depression_status,2 +20127-0.0,Neuroticism score,neuroticism_score,2 +1920-0.0,Mood swings,mood_swings,2 +1930-0.0,Miserableness,miserableness,2 +1940-0.0,Irritability,irritability,2 +1950-0.0,Sensitivity / hurt feelings,sensitivity_hurt_feelings,2 +1960-0.0,Fed-up feelings,fed_up_feelings,2 +1970-0.0,Nervous feelings,nervous_feelings,2 +1980-0.0,Worrier / anxious feelings,worry_anxiety_feelings,2 +1990-0.0,Tense / 'highly strung',tenseness_highly_strung,2 +2010-0.0,Suffer from 'nerves',suffering_from_nerves,2 +2020-0.0,"Loneliness, isolation",loneliness_isolation,2 +2030-0.0,Guilty feelings,guilty_feelings,2 +2040-0.0,Risk taking,risk_taking,2 +4526-0.0,Happiness,happiness,2 +4537-0.0,Work/job satisfaction,job_satisfaction,2 +4548-0.0,Health satisfaction,health_satisfaction,2 +4559-0.0,Family relationship satisfaction,family_relationship_satisfaction,2 +4570-0.0,Friendships satisfaction,friendship_satisfaction,2 +4581-0.0,Financial situation satisfaction,financial_situation_satisfaction,2 +2050-0.0,Frequency of depressed mood in last 2 weeks,depressed_mood_frequency_2_weeks,2 +2060-0.0,Frequency of unenthusiasm / disinterest in last 2 weeks,disinterest_frequency_2_weeks,2 +2070-0.0,Frequency of tenseness / restlessness in last 2 weeks,tenseness_restlessness_frequency_2_weeks,2 +2080-0.0,Frequency of tiredness / lethargy in last 2 weeks,tiredness_lethargy_frequency_2_weeks,2 +4598-0.0,Ever depressed for a whole week,ever_depressed_full_week,2 +4609-0.0,Longest period of depression,longest_depression_duration,2 +4620-0.0,Number of depression episodes,depression_episode_count,2 +5375-0.0,Longest period of unenthusiasm / disinterest,longest_disinterest_duration,2 +5386-0.0,Number of unenthusiastic/disinterested episodes,disinterest_episode_count,2 +4642-0.0,Ever manic/hyper for 2 days,ever_manic_hyper_2_days,2 +4653-0.0,Ever highly irritable/argumentative for 2 days,ever_irritable_argumentative_2_days,2 +6156-0.0,Manic/hyper symptoms,manic_hyper_symptoms,2 +5663-0.0,Length of longest manic/irritable episode,longest_manic_irritable_episode_duration,2 +5674-0.0,Severity of manic/irritable episodes,manic_irritable_episode_severity,2 +6145-0.0,"Illness, injury, bereavement, stress in last 2 years",adverse_life_events_2_years,2 +1050-0.0,Time spend outdoors in summer,outdoor_time_summer,2 +1060-0.0,Time spent outdoors in winter,outdoor_time_winter,2 +1727-0.0,Ease of skin tanning,skin_tanning_ease,2 +1737-0.0,Childhood sunburn occasions,childhood_sunburn_frequency,2 +2267-0.0,Use of sun/uv protection,sun_uv_protection_use,2 +2277-0.0,Frequency of solarium/sunlamp use,solarium_sunlamp_frequency,2 +24014-0.0,Close to major road,proximity_to_major_road,2 +24012-0.0,Inverse distance to the nearest major road,inverse_distance_nearest_major_road,2 +24010-0.0,Inverse distance to the nearest road,inverse_distance_nearest_road,2 +24016-0.0,Nitrogen dioxide air pollution; 2005,no2_2005,2 +24017-0.0,Nitrogen dioxide air pollution; 2006,no2_2006,2 +24018-0.0,Nitrogen dioxide air pollution; 2007,no2_2007,2 +24003-0.0,Nitrogen dioxide air pollution; 2010,no2_2010,2 +24004-0.0,Nitrogen oxides air pollution; 2010,nox_2010,2 +24019-0.0,Particulate matter air pollution (pm10); 2007,pm10_2007,2 +24005-0.0,Particulate matter air pollution (pm10); 2010,pm10_2010,2 +24007-0.0,Particulate matter air pollution (pm2.5) absorbance; 2010,pm25_absorbance_2010,2 +24006-0.0,Particulate matter air pollution (pm2.5); 2010,pm25_2010,2 +24008-0.0,Particulate matter air pollution 2.5-10um; 2010,pm25_10_2010,2 +24015-0.0,Sum of road length of major roads within 100m,major_road_length_100m,2 +24013-0.0,Total traffic load on major roads,major_road_traffic_load,2 +24011-0.0,Traffic intensity on the nearest major road,nearest_major_road_traffic_intensity,2 +24009-0.0,Traffic intensity on the nearest road,nearest_road_traffic_intensity,2 +24023-0.0,Average 16-hour sound level of noise pollution,noise_level_16h,2 +24024-0.0,Average 24-hour sound level of noise pollution,noise_level_24h,2 +24020-0.0,Average daytime sound level of noise pollution,noise_level_daytime,2 +24021-0.0,Average evening sound level of noise pollution,noise_level_evening,2 +24022-0.0,Average night-time sound level of noise pollution,noise_level_nighttime,2 +24506-0.0,"Natural environment percentage, buffer 1000m",natural_environment_percent_1000m,2 +24507-0.0,"Natural environment percentage, buffer 300m",natural_environment_percent_300m,2 +24500-0.0,"Greenspace percentage, buffer 1000m",greenspace_percent_1000m,2 +24503-0.0,"Greenspace percentage, buffer 300m",greenspace_percent_300m,2 +24501-0.0,"Domestic garden percentage, buffer 1000m",domestic_garden_percent_1000m,2 +24504-0.0,"Domestic garden percentage, buffer 300m",domestic_garden_percent_300m,2 +24502-0.0,"Water percentage, buffer 1000m",water_percent_1000m,2 +24505-0.0,"Water percentage, buffer 300m",water_percent_300m,2 +24508-0.0,Distance (Euclidean) to coast,distance_to_coast,2 +130000-0.0,Source of report of A00 (cholera),icd10_a00,3 +130002-0.0,Source of report of A01 (typhoid and paratyphoid fevers),icd10_a01,3 +130004-0.0,Source of report of A02 (other salmonella infections),icd10_a02,3 +130006-0.0,Source of report of A03 (shigellosis),icd10_a03,3 +130008-0.0,Source of report of A04 (other bacterial intestinal infections),icd10_a04,3 +130010-0.0,Source of report of A05 (other bacterial foodborne intoxications),icd10_a05,3 +130012-0.0,Source of report of A06 (amoebiasis),icd10_a06,3 +130014-0.0,Source of report of A07 (other protozoal intestinal diseases),icd10_a07,3 +130016-0.0,Source of report of A08 (viral and other specified intestinal infections),icd10_a08,3 +130018-0.0,Source of report of A09 (diarrhoea and gastro-enteritis of presumed infectious origin),icd10_a09,3 +130020-0.0,"Source of report of A15 (respiratory tuberculosis, bacteriologically and histologically confirmed)",icd10_a15,3 +130022-0.0,"Source of report of A16 (respiratory tuberculosis, not confirmed bacteriologically or histologically)",icd10_a16,3 +130024-0.0,Source of report of A17 (tuberculosis of nervous system),icd10_a17,3 +130026-0.0,Source of report of A18 (tuberculosis of other organs),icd10_a18,3 +130028-0.0,Source of report of A19 (miliary tuberculosis),icd10_a19,3 +130030-0.0,Source of report of A20 (plague),icd10_a20,3 +130034-0.0,Source of report of A22 (anthrax),icd10_a22,3 +130036-0.0,Source of report of A23 (brucellosis),icd10_a23,3 +130038-0.0,Source of report of A24 (glanders and melioidosis),icd10_a24,3 +130040-0.0,Source of report of A25 (rat-bite fevers),icd10_a25,3 +130042-0.0,Source of report of A26 (erysipeloid),icd10_a26,3 +130044-0.0,Source of report of A27 (leptospirosis),icd10_a27,3 +130046-0.0,"Source of report of A28 (other zoonotic bacterial diseases, not elsewhere classified)",icd10_a28,3 +130048-0.0,Source of report of A30 (leprosy [hansen's disease]),icd10_a30,3 +130050-0.0,Source of report of A31 (infection due to other mycobacteria),icd10_a31,3 +130052-0.0,Source of report of A32 (listeriosis),icd10_a32,3 +130054-0.0,Source of report of A33 (tetanus neonatorum),icd10_a33,3 +130058-0.0,Source of report of A35 (other tetanus),icd10_a35,3 +130060-0.0,Source of report of A36 (diphtheria),icd10_a36,3 +130062-0.0,Source of report of A37 (whooping cough),icd10_a37,3 +130064-0.0,Source of report of A38 (scarlet fever),icd10_a38,3 +130066-0.0,Source of report of A39 (meningococcal infection),icd10_a39,3 +130068-0.0,Source of report of A40 (streptococcal septicaemia),icd10_a40,3 +130070-0.0,Source of report of A41 (other septicaemia),icd10_a41,3 +130072-0.0,Source of report of A42 (actinomycosis),icd10_a42,3 +130074-0.0,Source of report of A43 (nocardiosis),icd10_a43,3 +130076-0.0,Source of report of A44 (bartonellosis),icd10_a44,3 +130078-0.0,Source of report of A46 (erysipelas),icd10_a46,3 +130080-0.0,"Source of report of A48 (other bacterial diseases, not elsewhere classified)",icd10_a48,3 +130082-0.0,Source of report of A49 (bacterial infection of unspecified site),icd10_a49,3 +130084-0.0,Source of report of A50 (congenital syphilis),icd10_a50,3 +130086-0.0,Source of report of A51 (early syphilis),icd10_a51,3 +130088-0.0,Source of report of A52 (late syphilis),icd10_a52,3 +130090-0.0,Source of report of A53 (other and unspecified syphilis),icd10_a53,3 +130092-0.0,Source of report of A54 (gonococcal infection),icd10_a54,3 +130094-0.0,Source of report of A55 (chlamydial lymphogranuloma (venereum)),icd10_a55,3 +130096-0.0,Source of report of A56 (other sexually transmitted chlamydial diseases),icd10_a56,3 +130100-0.0,Source of report of A58 (granuloma inguinale),icd10_a58,3 +130102-0.0,Source of report of A59 (trichomoniasis),icd10_a59,3 +130104-0.0,Source of report of A60 (anogenital herpesviral [herpes simplex] infections),icd10_a60,3 +130106-0.0,"Source of report of A63 (other predominantly sexually transmitted diseases, not elsewhere classified)",icd10_a63,3 +130108-0.0,Source of report of A64 (unspecified sexually transmitted disease),icd10_a64,3 +130112-0.0,Source of report of A66 (yaws),icd10_a66,3 +130114-0.0,Source of report of A67 (pinta [carate]),icd10_a67,3 +130116-0.0,Source of report of A68 (relapsing fevers),icd10_a68,3 +130118-0.0,Source of report of A69 (other spirochaetal infections),icd10_a69,3 +130120-0.0,Source of report of A70 (chlamydia psittaci infection),icd10_a70,3 +130122-0.0,Source of report of A71 (trachoma),icd10_a71,3 +130124-0.0,Source of report of A74 (other diseases caused by chlamydiae),icd10_a74,3 +130126-0.0,Source of report of A75 (typhus fever),icd10_a75,3 +130128-0.0,Source of report of A77 (spotted fever [tick-borne rickettsioses]),icd10_a77,3 +130130-0.0,Source of report of A78 (q fever),icd10_a78,3 +130132-0.0,Source of report of A79 (other rickettsioses),icd10_a79,3 +130134-0.0,Source of report of A80 (acute poliomyelitis),icd10_a80,3 +130136-0.0,Source of report of A81 (atypical virus infections of central nervous system),icd10_a81,3 +130138-0.0,Source of report of A82 (rabies),icd10_a82,3 +130140-0.0,Source of report of A83 (mosquito-borne viral encephalitis),icd10_a83,3 +130142-0.0,Source of report of A84 (tick-borne viral encephalitis),icd10_a84,3 +130144-0.0,"Source of report of A85 (other viral encephalitis, not elsewhere classified)",icd10_a85,3 +130146-0.0,Source of report of A86 (unspecified viral encephalitis),icd10_a86,3 +130148-0.0,Source of report of A87 (viral meningitis),icd10_a87,3 +130150-0.0,"Source of report of A88 (other viral infections of central nervous system, not elsewhere classified)",icd10_a88,3 +130152-0.0,Source of report of A89 (unspecified viral infection of central nervous system),icd10_a89,3 +130154-0.0,Source of report of A90 (dengue fever [classical dengue]),icd10_a90,3 +130156-0.0,Source of report of A91 (dengue haemorrhagic fever),icd10_a91,3 +130158-0.0,Source of report of A92 (other mosquito-borne viral fevers),icd10_a92,3 +130160-0.0,"Source of report of A93 (other arthropod-borne viral fevers, not elsewhere classified)",icd10_a93,3 +130162-0.0,Source of report of A94 (unspecified arthropod-borne viral fever),icd10_a94,3 +130164-0.0,Source of report of A95 (yellow fever),icd10_a95,3 +130168-0.0,Source of report of A97 (dengue),icd10_a97,3 +130170-0.0,"Source of report of A98 (other viral haemorrhagic fevers, not elsewhere classified)",icd10_a98,3 +130174-0.0,Source of report of B00 (herpesviral [herpes simplex] infections),icd10_b00,3 +130176-0.0,Source of report of B01 (varicella [chickenpox]),icd10_b01,3 +130178-0.0,Source of report of B02 (zoster [herpes zoster]),icd10_b02,3 +130180-0.0,Source of report of B03 (smallpox),icd10_b03,3 +130184-0.0,Source of report of B05 (measles),icd10_b05,3 +130186-0.0,Source of report of B06 (rubella [german measles]),icd10_b06,3 +130188-0.0,Source of report of B07 (viral warts),icd10_b07,3 +130190-0.0,"Source of report of B08 (other viral infections characterised by skin and mucous membrane lesions, not elsewhere classified)",icd10_b08,3 +130192-0.0,Source of report of B09 (unspecified viral infection characterised by skin and mucous membrane lesions),icd10_b09,3 +130194-0.0,Source of report of B15 (acute hepatitis a),icd10_b15,3 +130196-0.0,Source of report of B16 (acute hepatitis b),icd10_b16,3 +130198-0.0,Source of report of B17 (other acute viral hepatitis),icd10_b17,3 +130200-0.0,Source of report of B18 (chronic viral hepatitis),icd10_b18,3 +130202-0.0,Source of report of B19 (unspecified viral hepatitis),icd10_b19,3 +130204-0.0,Source of report of B20 (human immunodeficiency virus [hiv] disease resulting in infectious and parasitic diseases),icd10_b20,3 +130206-0.0,Source of report of B21 (human immunodeficiency virus [hiv] disease resulting in malignant neoplasms),icd10_b21,3 +130208-0.0,Source of report of B22 (human immunodeficiency virus [hiv] disease resulting in other specified diseases),icd10_b22,3 +130210-0.0,Source of report of B23 (human immunodeficiency virus [hiv] disease resulting in other conditions),icd10_b23,3 +130212-0.0,Source of report of B24 (unspecified human immunodeficiency virus [hiv] disease),icd10_b24,3 +130214-0.0,Source of report of B25 (cytomegaloviral disease),icd10_b25,3 +130216-0.0,Source of report of B26 (mumps),icd10_b26,3 +130218-0.0,Source of report of B27 (infectious mononucleosis),icd10_b27,3 +130220-0.0,Source of report of B30 (viral conjunctivitis),icd10_b30,3 +130222-0.0,"Source of report of B33 (other viral diseases, not elsewhere classified)",icd10_b33,3 +130224-0.0,Source of report of B34 (viral infection of unspecified site),icd10_b34,3 +130226-0.0,Source of report of B35 (dermatophytosis),icd10_b35,3 +130228-0.0,Source of report of B36 (other superficial mycoses),icd10_b36,3 +130230-0.0,Source of report of B37 (candidiasis),icd10_b37,3 +130232-0.0,Source of report of B38 (coccidioidomycosis),icd10_b38,3 +130234-0.0,Source of report of B39 (histoplasmosis),icd10_b39,3 +130236-0.0,Source of report of B40 (blastomycosis),icd10_b40,3 +130240-0.0,Source of report of B42 (sporotrichosis),icd10_b42,3 +130242-0.0,Source of report of B43 (chromomycosis and phaeomycotic abscess),icd10_b43,3 +130244-0.0,Source of report of B44 (aspergillosis),icd10_b44,3 +130246-0.0,Source of report of B45 (cryptococcosis),icd10_b45,3 +130248-0.0,Source of report of B46 (zygomycosis),icd10_b46,3 +130250-0.0,Source of report of B47 (mycetoma),icd10_b47,3 +130252-0.0,"Source of report of B48 (other mycoses, not elsewhere classified)",icd10_b48,3 +130254-0.0,Source of report of B49 (unspecified mycosis),icd10_b49,3 +130256-0.0,Source of report of B50 (plasmodium falciparum malaria),icd10_b50,3 +130258-0.0,Source of report of B51 (plasmodium vivax malaria),icd10_b51,3 +130260-0.0,Source of report of B52 (plasmodium malariae malaria),icd10_b52,3 +130262-0.0,Source of report of B53 (other parasitologically confirmed malaria),icd10_b53,3 +130264-0.0,Source of report of B54 (unspecified malaria),icd10_b54,3 +130266-0.0,Source of report of B55 (leishmaniasis),icd10_b55,3 +130270-0.0,Source of report of B57 (chagas' disease),icd10_b57,3 +130272-0.0,Source of report of B58 (toxoplasmosis),icd10_b58,3 +130274-0.0,Source of report of B59 (pneumocystosis),icd10_b59,3 +130276-0.0,"Source of report of B60 (other protozoal diseases, not elsewhere classified)",icd10_b60,3 +130280-0.0,Source of report of B65 (schistosomiasis [bilharziasis]),icd10_b65,3 +130282-0.0,Source of report of B66 (other fluke infections),icd10_b66,3 +130284-0.0,Source of report of B67 (echinococcosis),icd10_b67,3 +130286-0.0,Source of report of B68 (taeniasis),icd10_b68,3 +130288-0.0,Source of report of B69 (cysticercosis),icd10_b69,3 +130292-0.0,Source of report of B71 (other cestode infections),icd10_b71,3 +130296-0.0,Source of report of B73 (onchocerciasis),icd10_b73,3 +130298-0.0,Source of report of B74 (filariasis),icd10_b74,3 +130300-0.0,Source of report of B75 (trichinellosis),icd10_b75,3 +130302-0.0,Source of report of B76 (hookworm diseases),icd10_b76,3 +130304-0.0,Source of report of B77 (ascariasis),icd10_b77,3 +130306-0.0,Source of report of B78 (strongyloidiasis),icd10_b78,3 +130308-0.0,Source of report of B79 (trichuriasis),icd10_b79,3 +130310-0.0,Source of report of B80 (enterobiasis),icd10_b80,3 +130312-0.0,"Source of report of B81 (other intestinal helminthiases, not elsewhere classified)",icd10_b81,3 +130314-0.0,Source of report of B82 (unspecified intestinal parasitism),icd10_b82,3 +130316-0.0,Source of report of B83 (other helminthiases),icd10_b83,3 +130318-0.0,Source of report of B85 (pediculosis and phthiriasis),icd10_b85,3 +130320-0.0,Source of report of B86 (scabies),icd10_b86,3 +130322-0.0,Source of report of B87 (myiasis),icd10_b87,3 +130324-0.0,Source of report of B88 (other infestations),icd10_b88,3 +130326-0.0,Source of report of B89 (unspecified parasitic disease),icd10_b89,3 +130328-0.0,Source of report of B90 (sequelae of tuberculosis),icd10_b90,3 +130330-0.0,Source of report of B91 (sequelae of poliomyelitis),icd10_b91,3 +130334-0.0,Source of report of B94 (sequelae of other and unspecified infectious and parasitic diseases),icd10_b94,3 +130336-0.0,Source of report of B95 (streptococcus and staphylococcus as the cause of diseases classified to other chapters),icd10_b95,3 +130338-0.0,Source of report of B96 (other bacterial agents as the cause of diseases classified to other chapters),icd10_b96,3 +130340-0.0,Source of report of B97 (viral agents as the cause of diseases classified to other chapters),icd10_b97,3 +130342-0.0,Source of report of B98 (other specified infectious agents as the cause of diseases classified to other chapters),icd10_b98,3 +130344-0.0,Source of report of B99 (other and unspecified infectious diseases),icd10_b99,3 +130622-0.0,Source of report of D50 (iron deficiency anaemia),icd10_d50,3 +130624-0.0,Source of report of D51 (vitamin b12 deficiency anaemia),icd10_d51,3 +130626-0.0,Source of report of D52 (folate deficiency anaemia),icd10_d52,3 +130628-0.0,Source of report of D53 (other nutritional anaemias),icd10_d53,3 +130630-0.0,Source of report of D55 (anaemia due to enzyme disorders),icd10_d55,3 +130632-0.0,Source of report of D56 (thalassaemia),icd10_d56,3 +130634-0.0,Source of report of D57 (sickle-cell disorders),icd10_d57,3 +130636-0.0,Source of report of D58 (other hereditary haemolytic anaemias),icd10_d58,3 +130638-0.0,Source of report of D59 (acquired haemolytic anaemia),icd10_d59,3 +130640-0.0,Source of report of D60 (acquired pure red cell aplasia [erythroblastopenia]),icd10_d60,3 +130642-0.0,Source of report of D61 (other aplastic anaemias),icd10_d61,3 +130644-0.0,Source of report of D62 (acute posthaemorrhagic anaemia),icd10_d62,3 +130646-0.0,Source of report of D63 (anaemia in chronic diseases classified elsewhere),icd10_d63,3 +130648-0.0,Source of report of D64 (other anaemias),icd10_d64,3 +130650-0.0,Source of report of D65 (disseminated intravascular coagulation [defibrination syndrome]),icd10_d65,3 +130652-0.0,Source of report of D66 (hereditary factor viii deficiency),icd10_d66,3 +130654-0.0,Source of report of D67 (hereditary factor ix deficiency),icd10_d67,3 +130656-0.0,Source of report of D68 (other coagulation defects),icd10_d68,3 +130658-0.0,Source of report of D69 (purpura and other haemorrhagic conditions),icd10_d69,3 +130660-0.0,Source of report of D70 (agranulocytosis),icd10_d70,3 +130662-0.0,Source of report of D71 (functional disorders of polymorphonuclear neutrophils),icd10_d71,3 +130664-0.0,Source of report of D72 (other disorders of white blood cells),icd10_d72,3 +130666-0.0,Source of report of D73 (diseases of spleen),icd10_d73,3 +130668-0.0,Source of report of D74 (methaemoglobinaemia),icd10_d74,3 +130670-0.0,Source of report of D75 (other diseases of blood and blood-forming organs),icd10_d75,3 +130672-0.0,Source of report of D76 (certain diseases involving lymphoreticular tissue and reticulohistiocytic system),icd10_d76,3 +130674-0.0,Source of report of D77 (other disorders of blood and blood-forming organs in diseases classified elsewhere),icd10_d77,3 +130676-0.0,Source of report of D80 (immunodeficiency with predominantly antibody defects),icd10_d80,3 +130678-0.0,Source of report of D81 (combined immunodeficiencies),icd10_d81,3 +130680-0.0,Source of report of D82 (immunodeficiency associated with other major defects),icd10_d82,3 +130682-0.0,Source of report of D83 (common variable immunodeficiency),icd10_d83,3 +130684-0.0,Source of report of D84 (other immunodeficiencies),icd10_d84,3 +130686-0.0,Source of report of D86 (sarcoidosis),icd10_d86,3 +130688-0.0,"Source of report of D89 (other disorders involving the immune mechanism, not elsewhere classified)",icd10_d89,3 +130692-0.0,Source of report of E01 (iodine-deficiency-related thyroid disorders and allied conditions),icd10_e01,3 +130694-0.0,Source of report of E02 (subclinical iodine-deficiency hypothyroidism),icd10_e02,3 +130696-0.0,Source of report of E03 (other hypothyroidism),icd10_e03,3 +130698-0.0,Source of report of E04 (other non-toxic goitre),icd10_e04,3 +130700-0.0,Source of report of E05 (thyrotoxicosis [hyperthyroidism]),icd10_e05,3 +130702-0.0,Source of report of E06 (thyroiditis),icd10_e06,3 +130704-0.0,Source of report of E07 (other disorders of thyroid),icd10_e07,3 +130706-0.0,Source of report of E10 (insulin-dependent diabetes mellitus),icd10_e10,3 +130708-0.0,Source of report of E11 (non-insulin-dependent diabetes mellitus),icd10_e11,3 +130710-0.0,Source of report of E12 (malnutrition-related diabetes mellitus),icd10_e12,3 +130712-0.0,Source of report of E13 (other specified diabetes mellitus),icd10_e13,3 +130714-0.0,Source of report of E14 (unspecified diabetes mellitus),icd10_e14,3 +130716-0.0,Source of report of E15 (nondiabetic hypoglycaemic coma),icd10_e15,3 +130718-0.0,Source of report of E16 (other disorders of pancreatic internal secretion),icd10_e16,3 +130720-0.0,Source of report of E20 (hypoparathyroidism),icd10_e20,3 +130722-0.0,Source of report of E21 (hyperparathyroidism and other disorders of parathyroid gland),icd10_e21,3 +130724-0.0,Source of report of E22 (hyperfunction of pituitary gland),icd10_e22,3 +130726-0.0,Source of report of E23 (hypofunction and other disorders of pituitary gland),icd10_e23,3 +130728-0.0,Source of report of E24 (cushing's syndrome),icd10_e24,3 +130730-0.0,Source of report of E25 (adrenogenital disorders),icd10_e25,3 +130732-0.0,Source of report of E26 (hyperaldosteronism),icd10_e26,3 +130734-0.0,Source of report of E27 (other disorders of adrenal gland),icd10_e27,3 +130736-0.0,Source of report of E28 (ovarian dysfunction),icd10_e28,3 +130738-0.0,Source of report of E29 (testicular dysfunction),icd10_e29,3 +130740-0.0,"Source of report of E30 (disorders of puberty, not elsewhere classified)",icd10_e30,3 +130742-0.0,Source of report of E31 (polyglandular dysfunction),icd10_e31,3 +130744-0.0,Source of report of E32 (diseases of thymus),icd10_e32,3 +130746-0.0,Source of report of E34 (other endocrine disorders),icd10_e34,3 +130748-0.0,Source of report of E35 (disorders of endocrine glands in diseases classified elsewhere),icd10_e35,3 +130752-0.0,Source of report of E41 (nutritional marasmus),icd10_e41,3 +130756-0.0,Source of report of E43 (unspecified severe protein-energy malnutrition),icd10_e43,3 +130758-0.0,Source of report of E44 (protein-energy malnutrition of moderate and mild degree),icd10_e44,3 +130760-0.0,Source of report of E45 (retarded development following protein-energy malnutrition),icd10_e45,3 +130762-0.0,Source of report of E46 (unspecified protein-energy malnutrition),icd10_e46,3 +130764-0.0,Source of report of E50 (vitamin a deficiency),icd10_e50,3 +130766-0.0,Source of report of E51 (thiamine deficiency),icd10_e51,3 +130768-0.0,Source of report of E52 (niacin deficiency [pellagra]),icd10_e52,3 +130770-0.0,Source of report of E53 (deficiency of other b group vitamins),icd10_e53,3 +130772-0.0,Source of report of E54 (ascorbic acid deficiency),icd10_e54,3 +130774-0.0,Source of report of E55 (vitamin d deficiency),icd10_e55,3 +130776-0.0,Source of report of E56 (other vitamin deficiencies),icd10_e56,3 +130778-0.0,Source of report of E58 (dietary calcium deficiency),icd10_e58,3 +130780-0.0,Source of report of E59 (dietary selenium deficiency),icd10_e59,3 +130782-0.0,Source of report of E60 (dietary zinc deficiency),icd10_e60,3 +130784-0.0,Source of report of E61 (deficiency of other nutrient elements),icd10_e61,3 +130786-0.0,Source of report of E63 (other nutritional deficiencies),icd10_e63,3 +130788-0.0,Source of report of E64 (sequelae of malnutrition and other nutritional deficiencies),icd10_e64,3 +130790-0.0,Source of report of E65 (localised adiposity),icd10_e65,3 +130792-0.0,Source of report of E66 (obesity),icd10_e66,3 +130794-0.0,Source of report of E67 (other hyperalimentation),icd10_e67,3 +130796-0.0,Source of report of E68 (sequelae of hyperalimentation),icd10_e68,3 +130798-0.0,Source of report of E70 (disorders of aromatic amino-acid metabolism),icd10_e70,3 +130800-0.0,Source of report of E71 (disorders of branched-chain amino-acid metabolism and fatty-acid metabolism),icd10_e71,3 +130802-0.0,Source of report of E72 (other disorders of amino-acid metabolism),icd10_e72,3 +130804-0.0,Source of report of E73 (lactose intolerance),icd10_e73,3 +130806-0.0,Source of report of E74 (other disorders of carbohydrate metabolism),icd10_e74,3 +130808-0.0,Source of report of E75 (disorders of sphingolipid metabolism and other lipid storage disorders),icd10_e75,3 +130810-0.0,Source of report of E76 (disorders of glycosaminoglycan metabolism),icd10_e76,3 +130812-0.0,Source of report of E77 (disorders of glycoprotein metabolism),icd10_e77,3 +130814-0.0,Source of report of E78 (disorders of lipoprotein metabolism and other lipidaemias),icd10_e78,3 +130816-0.0,Source of report of E79 (disorders of purine and pyrimidine metabolism),icd10_e79,3 +130818-0.0,Source of report of E80 (disorders of porphyrin and bilirubin metabolism),icd10_e80,3 +130820-0.0,Source of report of E83 (disorders of mineral metabolism),icd10_e83,3 +130822-0.0,Source of report of E84 (cystic fibrosis),icd10_e84,3 +130824-0.0,Source of report of E85 (amyloidosis),icd10_e85,3 +130826-0.0,Source of report of E86 (volume depletion),icd10_e86,3 +130828-0.0,"Source of report of E87 (other disorders of fluid, electrolyte and acid-base balance)",icd10_e87,3 +130830-0.0,Source of report of E88 (other metabolic disorders),icd10_e88,3 +130832-0.0,"Source of report of E89 (postprocedural endocrine and metabolic disorders, not elsewhere classified)",icd10_e89,3 +130836-0.0,Source of report of F00 (dementia in alzheimer's disease),icd10_f00,3 +130838-0.0,Source of report of F01 (vascular dementia),icd10_f01,3 +130840-0.0,Source of report of F02 (dementia in other diseases classified elsewhere),icd10_f02,3 +130842-0.0,Source of report of F03 (unspecified dementia),icd10_f03,3 +130844-0.0,"Source of report of F04 (organic amnesic syndrome, not induced by alcohol and other psychoactive substances)",icd10_f04,3 +130846-0.0,"Source of report of F05 (delirium, not induced by alcohol and other psychoactive substances)",icd10_f05,3 +130848-0.0,Source of report of F06 (other mental disorders due to brain damage and dysfunction and to physical disease),icd10_f06,3 +130850-0.0,"Source of report of F07 (personality and behavioural disorders due to brain disease, damage and dysfunction)",icd10_f07,3 +130852-0.0,Source of report of F09 (unspecified organic or symptomatic mental disorder),icd10_f09,3 +130854-0.0,Source of report of F10 (mental and behavioural disorders due to use of alcohol),icd10_f10,3 +130856-0.0,Source of report of F11 (mental and behavioural disorders due to use of opioids),icd10_f11,3 +130858-0.0,Source of report of F12 (mental and behavioural disorders due to use of cannabinoids),icd10_f12,3 +130860-0.0,Source of report of F13 (mental and behavioural disorders due to use of sedatives or hypnotics),icd10_f13,3 +130862-0.0,Source of report of F14 (mental and behavioural disorders due to use of cocaine),icd10_f14,3 +130864-0.0,"Source of report of F15 (mental and behavioural disorders due to use of other stimulants, including caffeine)",icd10_f15,3 +130866-0.0,Source of report of F16 (mental and behavioural disorders due to use of hallucinogens),icd10_f16,3 +130868-0.0,Source of report of F17 (mental and behavioural disorders due to use of tobacco),icd10_f17,3 +130870-0.0,Source of report of F18 (mental and behavioural disorders due to use of volatile solvents),icd10_f18,3 +130872-0.0,Source of report of F19 (mental and behavioural disorders due to multiple drug use and use of other psychoactive substances),icd10_f19,3 +130874-0.0,Source of report of F20 (schizophrenia),icd10_f20,3 +130876-0.0,Source of report of F21 (schizotypal disorder),icd10_f21,3 +130878-0.0,Source of report of F22 (persistent delusional disorders),icd10_f22,3 +130880-0.0,Source of report of F23 (acute and transient psychotic disorders),icd10_f23,3 +130882-0.0,Source of report of F24 (induced delusional disorder),icd10_f24,3 +130884-0.0,Source of report of F25 (schizoaffective disorders),icd10_f25,3 +130886-0.0,Source of report of F28 (other nonorganic psychotic disorders),icd10_f28,3 +130888-0.0,Source of report of F29 (unspecified nonorganic psychosis),icd10_f29,3 +130890-0.0,Source of report of F30 (manic episode),icd10_f30,3 +130892-0.0,Source of report of F31 (bipolar affective disorder),icd10_f31,3 +130894-0.0,Source of report of F32 (depressive episode),icd10_f32,3 +130896-0.0,Source of report of F33 (recurrent depressive disorder),icd10_f33,3 +130898-0.0,Source of report of F34 (persistent mood [affective] disorders),icd10_f34,3 +130900-0.0,Source of report of F38 (other mood [affective] disorders),icd10_f38,3 +130902-0.0,Source of report of F39 (unspecified mood [affective] disorder),icd10_f39,3 +130904-0.0,Source of report of F40 (phobic anxiety disorders),icd10_f40,3 +130906-0.0,Source of report of F41 (other anxiety disorders),icd10_f41,3 +130908-0.0,Source of report of F42 (obsessive-compulsive disorder),icd10_f42,3 +130910-0.0,"Source of report of F43 (reaction to severe stress, and adjustment disorders)",icd10_f43,3 +130912-0.0,Source of report of F44 (dissociative [conversion] disorders),icd10_f44,3 +130914-0.0,Source of report of F45 (somatoform disorders),icd10_f45,3 +130916-0.0,Source of report of F48 (other neurotic disorders),icd10_f48,3 +130918-0.0,Source of report of F50 (eating disorders),icd10_f50,3 +130920-0.0,Source of report of F51 (nonorganic sleep disorders),icd10_f51,3 +130922-0.0,"Source of report of F52 (sexual dysfunction, not caused by organic disorder or disease)",icd10_f52,3 +130924-0.0,"Source of report of F53 (mental and behavioural disorders associated with the puerperium, not elsewhere classified)",icd10_f53,3 +130926-0.0,Source of report of F54 (psychological and behavioural factors associated with disorders or diseases classified elsewhere),icd10_f54,3 +130928-0.0,Source of report of F55 (abuse of non-dependence-producing substances),icd10_f55,3 +130930-0.0,Source of report of F59 (unspecified behavioural syndromes associated with physiological disturbances and physical factors),icd10_f59,3 +130932-0.0,Source of report of F60 (specific personality disorders),icd10_f60,3 +130934-0.0,Source of report of F61 (mixed and other personality disorders),icd10_f61,3 +130936-0.0,"Source of report of F62 (enduring personality changes, not attributable to brain damage and disease)",icd10_f62,3 +130938-0.0,Source of report of F63 (habit and impulse disorders),icd10_f63,3 +130940-0.0,Source of report of F64 (gender identity disorders),icd10_f64,3 +130942-0.0,Source of report of F65 (disorders of sexual preference),icd10_f65,3 +130944-0.0,Source of report of F66 (psychological and behavioural disorders associated with sexual development and orientation),icd10_f66,3 +130946-0.0,Source of report of F68 (other disorders of adult personality and behaviour),icd10_f68,3 +130948-0.0,Source of report of F69 (unspecified disorder of adult personality and behaviour),icd10_f69,3 +130950-0.0,Source of report of F70 (mild mental retardation),icd10_f70,3 +130952-0.0,Source of report of F71 (moderate mental retardation),icd10_f71,3 +130954-0.0,Source of report of F72 (severe mental retardation),icd10_f72,3 +130958-0.0,Source of report of F78 (other mental retardation),icd10_f78,3 +130960-0.0,Source of report of F79 (unspecified mental retardation),icd10_f79,3 +130962-0.0,Source of report of F80 (specific developmental disorders of speech and language),icd10_f80,3 +130964-0.0,Source of report of F81 (specific developmental disorders of scholastic skills),icd10_f81,3 +130966-0.0,Source of report of F82 (specific developmental disorder of motor function),icd10_f82,3 +130968-0.0,Source of report of F83 (mixed specific developmental disorders),icd10_f83,3 +130970-0.0,Source of report of F84 (pervasive developmental disorders),icd10_f84,3 +130972-0.0,Source of report of F88 (other disorders of psychological development),icd10_f88,3 +130974-0.0,Source of report of F89 (unspecified disorder of psychological development),icd10_f89,3 +130976-0.0,Source of report of F90 (hyperkinetic disorders),icd10_f90,3 +130978-0.0,Source of report of F91 (conduct disorders),icd10_f91,3 +130980-0.0,Source of report of F92 (mixed disorders of conduct and emotions),icd10_f92,3 +130982-0.0,Source of report of F93 (emotional disorders with onset specific to childhood),icd10_f93,3 +130984-0.0,Source of report of F94 (disorders of social functioning with onset specific to childhood and adolescence),icd10_f94,3 +130986-0.0,Source of report of F95 (tic disorders),icd10_f95,3 +130988-0.0,Source of report of F98 (other behavioural and emotional disorders with onset usually occurring in childhood and adolescence),icd10_f98,3 +130990-0.0,"Source of report of F99 (mental disorder, not otherwise specified)",icd10_f99,3 +130992-0.0,"Source of report of G00 (bacterial meningitis, not elsewhere classified)",icd10_g00,3 +130994-0.0,Source of report of G01 (meningitis in bacterial diseases classified elsewhere),icd10_g01,3 +130996-0.0,Source of report of G02 (meningitis in other infectious and parasitic diseases classified elsewhere),icd10_g02,3 +130998-0.0,Source of report of G03 (meningitis due to other and unspecified causes),icd10_g03,3 +131000-0.0,"Source of report of G04 (encephalitis, myelitis and encephalomyelitis)",icd10_g04,3 +131002-0.0,"Source of report of G05 (encephalitis, myelitis and encephalomyelitis in diseases classified elsewhere)",icd10_g05,3 +131004-0.0,Source of report of G06 (intracranial and intraspinal abscess and granuloma),icd10_g06,3 +131006-0.0,Source of report of G07 (intracranial and intraspinal abscess and granuloma in diseases classified elsewhere),icd10_g07,3 +131008-0.0,Source of report of G08 (intracranial and intraspinal phlebitis and thrombophlebitis),icd10_g08,3 +131010-0.0,Source of report of G09 (sequelae of inflammatory diseases of central nervous system),icd10_g09,3 +131012-0.0,Source of report of G10 (huntington's disease),icd10_g10,3 +131014-0.0,Source of report of G11 (hereditary ataxia),icd10_g11,3 +131016-0.0,Source of report of G12 (spinal muscular atrophy and related syndromes),icd10_g12,3 +131018-0.0,Source of report of G13 (systemic atrophies primarily affecting central nervous system in diseases classified elsewhere),icd10_g13,3 +131020-0.0,Source of report of G14 (postpolio syndrome),icd10_g14,3 +131022-0.0,Source of report of G20 (parkinson's disease),icd10_g20,3 +131024-0.0,Source of report of G21 (secondary parkinsonism),icd10_g21,3 +131026-0.0,Source of report of G22 (parkinsonism in diseases classified elsewhere),icd10_g22,3 +131028-0.0,Source of report of G23 (other degenerative diseases of basal ganglia),icd10_g23,3 +131030-0.0,Source of report of G24 (dystonia),icd10_g24,3 +131032-0.0,Source of report of G25 (other extrapyramidal and movement disorders),icd10_g25,3 +131036-0.0,Source of report of G30 (alzheimer's disease),icd10_g30,3 +131038-0.0,"Source of report of G31 (other degenerative diseases of nervous system, not elsewhere classified)",icd10_g31,3 +131040-0.0,Source of report of G32 (other degenerative disorders of nervous system in diseases classified elsewhere),icd10_g32,3 +131042-0.0,Source of report of G35 (multiple sclerosis),icd10_g35,3 +131044-0.0,Source of report of G36 (other acute disseminated demyelination),icd10_g36,3 +131046-0.0,Source of report of G37 (other demyelinating diseases of central nervous system),icd10_g37,3 +131048-0.0,Source of report of G40 (epilepsy),icd10_g40,3 +131050-0.0,Source of report of G41 (status epilepticus),icd10_g41,3 +131052-0.0,Source of report of G43 (migraine),icd10_g43,3 +131054-0.0,Source of report of G44 (other headache syndromes),icd10_g44,3 +131056-0.0,Source of report of G45 (transient cerebral ischaemic attacks and related syndromes),icd10_g45,3 +131058-0.0,Source of report of G46 (vascular syndromes of brain in cerebrovascular diseases),icd10_g46,3 +131060-0.0,Source of report of G47 (sleep disorders),icd10_g47,3 +131062-0.0,Source of report of G50 (disorders of trigeminal nerve),icd10_g50,3 +131064-0.0,Source of report of G51 (facial nerve disorders),icd10_g51,3 +131066-0.0,Source of report of G52 (disorders of other cranial nerves),icd10_g52,3 +131068-0.0,Source of report of G53 (cranial nerve disorders in diseases classified elsewhere),icd10_g53,3 +131070-0.0,Source of report of G54 (nerve root and plexus disorders),icd10_g54,3 +131072-0.0,Source of report of G55 (nerve root and plexus compressions in diseases classified elsewhere),icd10_g55,3 +131074-0.0,Source of report of G56 (mononeuropathies of upper limb),icd10_g56,3 +131076-0.0,Source of report of G57 (mononeuropathies of lower limb),icd10_g57,3 +131078-0.0,Source of report of G58 (other mononeuropathies),icd10_g58,3 +131080-0.0,Source of report of G59 (mononeuropathy in diseases classified elsewhere),icd10_g59,3 +131082-0.0,Source of report of G60 (hereditary and idiopathic neuropathy),icd10_g60,3 +131084-0.0,Source of report of G61 (inflammatory polyneuropathy),icd10_g61,3 +131086-0.0,Source of report of G62 (other polyneuropathies),icd10_g62,3 +131088-0.0,Source of report of G63 (polyneuropathy in diseases classified elsewhere),icd10_g63,3 +131090-0.0,Source of report of G64 (other disorders of peripheral nervous system),icd10_g64,3 +131092-0.0,Source of report of G70 (myasthenia gravis and other myoneural disorders),icd10_g70,3 +131094-0.0,Source of report of G71 (primary disorders of muscles),icd10_g71,3 +131096-0.0,Source of report of G72 (other myopathies),icd10_g72,3 +131098-0.0,Source of report of G73 (disorders of myoneural junction and muscle in diseases classified elsewhere),icd10_g73,3 +131100-0.0,Source of report of G80 (infantile cerebral palsy),icd10_g80,3 +131102-0.0,Source of report of G81 (hemiplegia),icd10_g81,3 +131104-0.0,Source of report of G82 (paraplegia and tetraplegia),icd10_g82,3 +131106-0.0,Source of report of G83 (other paralytic syndromes),icd10_g83,3 +131108-0.0,Source of report of G90 (disorders of autonomic nervous system),icd10_g90,3 +131110-0.0,Source of report of G91 (hydrocephalus),icd10_g91,3 +131112-0.0,Source of report of G92 (toxic encephalopathy),icd10_g92,3 +131114-0.0,Source of report of G93 (other disorders of brain),icd10_g93,3 +131116-0.0,Source of report of G94 (other disorders of brain in diseases classified elsewhere),icd10_g94,3 +131118-0.0,Source of report of G95 (other diseases of spinal cord),icd10_g95,3 +131120-0.0,Source of report of G96 (other disorders of central nervous system),icd10_g96,3 +131122-0.0,"Source of report of G97 (postprocedural disorders of nervous system, not elsewhere classified)",icd10_g97,3 +131124-0.0,"Source of report of G98 (other disorders of nervous system, not elsewhere classified)",icd10_g98,3 +131126-0.0,Source of report of G99 (other disorders of nervous system in diseases classified elsewhere),icd10_g99,3 +131128-0.0,Source of report of H00 (hordeolum and chalazion),icd10_h00,3 +131130-0.0,Source of report of H01 (other inflammation of eyelid),icd10_h01,3 +131132-0.0,Source of report of H02 (other disorders of eyelid),icd10_h02,3 +131134-0.0,Source of report of H03 (disorders of eyelid in diseases classified elsewhere),icd10_h03,3 +131136-0.0,Source of report of H04 (disorders of lachrymal system),icd10_h04,3 +131138-0.0,Source of report of H05 (disorders of orbit),icd10_h05,3 +131140-0.0,Source of report of H06 (disorders of lachrymal system and orbit in diseases classified elsewhere),icd10_h06,3 +131142-0.0,Source of report of H10 (conjunctivitis),icd10_h10,3 +131144-0.0,Source of report of H11 (other disorders of conjunctiva),icd10_h11,3 +131146-0.0,Source of report of H13 (disorders of conjunctiva in diseases classified elsewhere),icd10_h13,3 +131148-0.0,Source of report of H15 (disorders of sclera),icd10_h15,3 +131150-0.0,Source of report of H16 (keratitis),icd10_h16,3 +131152-0.0,Source of report of H17 (corneal scars and opacities),icd10_h17,3 +131154-0.0,Source of report of H18 (other disorders of cornea),icd10_h18,3 +131156-0.0,Source of report of H19 (disorders of sclera and cornea in diseases classified elsewhere),icd10_h19,3 +131158-0.0,Source of report of H20 (iridocyclitis),icd10_h20,3 +131160-0.0,Source of report of H21 (other disorders of iris and ciliary body),icd10_h21,3 +131162-0.0,Source of report of H22 (disorders of iris and ciliary body in diseases classified elsewhere),icd10_h22,3 +131164-0.0,Source of report of H25 (senile cataract),icd10_h25,3 +131166-0.0,Source of report of H26 (other cataract),icd10_h26,3 +131168-0.0,Source of report of H27 (other disorders of lens),icd10_h27,3 +131170-0.0,Source of report of H28 (cataract and other disorders of lens in diseases classified elsewhere),icd10_h28,3 +131172-0.0,Source of report of H30 (chorioretinal inflammation),icd10_h30,3 +131174-0.0,Source of report of H31 (other disorders of choroid),icd10_h31,3 +131176-0.0,Source of report of H32 (chorioretinal disorders in diseases classified elsewhere),icd10_h32,3 +131178-0.0,Source of report of H33 (retinal detachments and breaks),icd10_h33,3 +131180-0.0,Source of report of H34 (retinal vascular occlusions),icd10_h34,3 +131182-0.0,Source of report of H35 (other retinal disorders),icd10_h35,3 +131184-0.0,Source of report of H36 (retinal disorders in diseases classified elsewhere),icd10_h36,3 +131186-0.0,Source of report of H40 (glaucoma),icd10_h40,3 +131188-0.0,Source of report of H42 (glaucoma in diseases classified elsewhere),icd10_h42,3 +131190-0.0,Source of report of H43 (disorders of vitreous body),icd10_h43,3 +131192-0.0,Source of report of H44 (disorders of globe),icd10_h44,3 +131194-0.0,Source of report of H45 (disorders of vitreous body and globe in diseases classified elsewhere),icd10_h45,3 +131196-0.0,Source of report of H46 (optic neuritis),icd10_h46,3 +131198-0.0,Source of report of H47 (other disorders of optic [2nd] nerve and visual pathways),icd10_h47,3 +131200-0.0,Source of report of H48 (disorders of optic [2nd] nerve and visual pathways in diseases classified elsewhere),icd10_h48,3 +131202-0.0,Source of report of H49 (paralytic strabismus),icd10_h49,3 +131204-0.0,Source of report of H50 (other strabismus),icd10_h50,3 +131206-0.0,Source of report of H51 (other disorders of binocular movement),icd10_h51,3 +131208-0.0,Source of report of H52 (disorders of refraction and accommodation),icd10_h52,3 +131210-0.0,Source of report of H53 (visual disturbances),icd10_h53,3 +131212-0.0,Source of report of H54 (blindness and low vision),icd10_h54,3 +131214-0.0,Source of report of H55 (nystagmus and other irregular eye movements),icd10_h55,3 +131216-0.0,Source of report of H57 (other disorders of eye and adnexa),icd10_h57,3 +131218-0.0,Source of report of H58 (other disorders of eye and adnexa in diseases classified elsewhere),icd10_h58,3 +131220-0.0,"Source of report of H59 (postprocedural disorders of eye and adnexa, not elsewhere classified)",icd10_h59,3 +131222-0.0,Source of report of H60 (otitis externa),icd10_h60,3 +131224-0.0,Source of report of H61 (other disorders of external ear),icd10_h61,3 +131226-0.0,Source of report of H62 (disorders of external ear in diseases classified elsewhere),icd10_h62,3 +131228-0.0,Source of report of H65 (nonsuppurative otitis media),icd10_h65,3 +131230-0.0,Source of report of H66 (suppurative and unspecified otitis media),icd10_h66,3 +131232-0.0,Source of report of H67 (otitis media in diseases classified elsewhere),icd10_h67,3 +131234-0.0,Source of report of H68 (eustachian salpingitis and obstruction),icd10_h68,3 +131236-0.0,Source of report of H69 (other disorders of eustachian tube),icd10_h69,3 +131238-0.0,Source of report of H70 (mastoiditis and related conditions),icd10_h70,3 +131240-0.0,Source of report of H71 (cholesteatoma of middle ear),icd10_h71,3 +131242-0.0,Source of report of H72 (perforation of tympanic membrane),icd10_h72,3 +131244-0.0,Source of report of H73 (other disorders of tympanic membrane),icd10_h73,3 +131246-0.0,Source of report of H74 (other disorders of middle ear and mastoid),icd10_h74,3 +131248-0.0,Source of report of H75 (other disorders of middle ear and mastoid in diseases classified elsewhere),icd10_h75,3 +131250-0.0,Source of report of H80 (otosclerosis),icd10_h80,3 +131252-0.0,Source of report of H81 (disorders of vestibular function),icd10_h81,3 +131254-0.0,Source of report of H82 (vertiginous syndromes in diseases classified elsewhere),icd10_h82,3 +131256-0.0,Source of report of H83 (other diseases of inner ear),icd10_h83,3 +131258-0.0,Source of report of H90 (conductive and sensorineural hearing loss),icd10_h90,3 +131260-0.0,Source of report of H91 (other hearing loss),icd10_h91,3 +131262-0.0,Source of report of H92 (otalgia and effusion of ear),icd10_h92,3 +131264-0.0,"Source of report of H93 (other disorders of ear, not elsewhere classified)",icd10_h93,3 +131266-0.0,Source of report of H94 (other disorders of ear in diseases classified elsewhere),icd10_h94,3 +131268-0.0,"Source of report of H95 (postprocedural disorders of ear and mastoid process, not elsewhere classified)",icd10_h95,3 +131270-0.0,Source of report of I00 (rheumatic fever without mention of heart involvement),icd10_i00,3 +131272-0.0,Source of report of I01 (rheumatic fever with heart involvement),icd10_i01,3 +131274-0.0,Source of report of I02 (rheumatic chorea),icd10_i02,3 +131276-0.0,Source of report of I05 (rheumatic mitral valve diseases),icd10_i05,3 +131278-0.0,Source of report of I06 (rheumatic aortic valve diseases),icd10_i06,3 +131280-0.0,Source of report of I07 (rheumatic tricuspid valve diseases),icd10_i07,3 +131282-0.0,Source of report of I08 (multiple valve diseases),icd10_i08,3 +131284-0.0,Source of report of I09 (other rheumatic heart diseases),icd10_i09,3 +131286-0.0,Source of report of I10 (essential (primary) hypertension),icd10_i10,3 +131288-0.0,Source of report of I11 (hypertensive heart disease),icd10_i11,3 +131290-0.0,Source of report of I12 (hypertensive renal disease),icd10_i12,3 +131292-0.0,Source of report of I13 (hypertensive heart and renal disease),icd10_i13,3 +131294-0.0,Source of report of I15 (secondary hypertension),icd10_i15,3 +131296-0.0,Source of report of I20 (angina pectoris),icd10_i20,3 +131298-0.0,Source of report of I21 (acute myocardial infarction),icd10_i21,3 +131300-0.0,Source of report of I22 (subsequent myocardial infarction),icd10_i22,3 +131302-0.0,Source of report of I23 (certain current complications following acute myocardial infarction),icd10_i23,3 +131304-0.0,Source of report of I24 (other acute ischaemic heart diseases),icd10_i24,3 +131306-0.0,Source of report of I25 (chronic ischaemic heart disease),icd10_i25,3 +131308-0.0,Source of report of I26 (pulmonary embolism),icd10_i26,3 +131310-0.0,Source of report of I27 (other pulmonary heart diseases),icd10_i27,3 +131312-0.0,Source of report of I28 (other diseases of pulmonary vessels),icd10_i28,3 +131314-0.0,Source of report of I30 (acute pericarditis),icd10_i30,3 +131316-0.0,Source of report of I31 (other diseases of pericardium),icd10_i31,3 +131318-0.0,Source of report of I32 (pericarditis in diseases classified elsewhere),icd10_i32,3 +131320-0.0,Source of report of I33 (acute and subacute endocarditis),icd10_i33,3 +131322-0.0,Source of report of I34 (nonrheumatic mitral valve disorders),icd10_i34,3 +131324-0.0,Source of report of I35 (nonrheumatic aortic valve disorders),icd10_i35,3 +131326-0.0,Source of report of I36 (nonrheumatic tricuspid valve disorders),icd10_i36,3 +131328-0.0,Source of report of I37 (pulmonary valve disorders),icd10_i37,3 +131330-0.0,"Source of report of I38 (endocarditis, valve unspecified)",icd10_i38,3 +131332-0.0,Source of report of I39 (endocarditis and heart valve disorders in diseases classified elsewhere),icd10_i39,3 +131334-0.0,Source of report of I40 (acute myocarditis),icd10_i40,3 +131336-0.0,Source of report of I41 (myocarditis in diseases classified elsewhere),icd10_i41,3 +131338-0.0,Source of report of I42 (cardiomyopathy),icd10_i42,3 +131340-0.0,Source of report of I43 (cardiomyopathy in diseases classified elsewhere),icd10_i43,3 +131342-0.0,Source of report of I44 (atrioventricular and left bundle-branch block),icd10_i44,3 +131344-0.0,Source of report of I45 (other conduction disorders),icd10_i45,3 +131346-0.0,Source of report of I46 (cardiac arrest),icd10_i46,3 +131348-0.0,Source of report of I47 (paroxysmal tachycardia),icd10_i47,3 +131350-0.0,Source of report of I48 (atrial fibrillation and flutter),icd10_i48,3 +131352-0.0,Source of report of I49 (other cardiac arrhythmias),icd10_i49,3 +131354-0.0,Source of report of I50 (heart failure),icd10_i50,3 +131356-0.0,Source of report of I51 (complications and ill-defined descriptions of heart disease),icd10_i51,3 +131358-0.0,Source of report of I52 (other heart disorders in diseases classified elsewhere),icd10_i52,3 +131360-0.0,Source of report of I60 (subarachnoid haemorrhage),icd10_i60,3 +131362-0.0,Source of report of I61 (intracerebral haemorrhage),icd10_i61,3 +131364-0.0,Source of report of I62 (other nontraumatic intracranial haemorrhage),icd10_i62,3 +131366-0.0,Source of report of I63 (cerebral infarction),icd10_i63,3 +131368-0.0,"Source of report of I64 (stroke, not specified as haemorrhage or infarction)",icd10_i64,3 +131370-0.0,"Source of report of I65 (occlusion and stenosis of precerebral arteries, not resulting in cerebral infarction)",icd10_i65,3 +131372-0.0,"Source of report of I66 (occlusion and stenosis of cerebral arteries, not resulting in cerebral infarction)",icd10_i66,3 +131374-0.0,Source of report of I67 (other cerebrovascular diseases),icd10_i67,3 +131376-0.0,Source of report of I68 (cerebrovascular disorders in diseases classified elsewhere),icd10_i68,3 +131378-0.0,Source of report of I69 (sequelae of cerebrovascular disease),icd10_i69,3 +131380-0.0,Source of report of I70 (atherosclerosis),icd10_i70,3 +131382-0.0,Source of report of I71 (aortic aneurysm and dissection),icd10_i71,3 +131384-0.0,Source of report of I72 (other aneurysm),icd10_i72,3 +131386-0.0,Source of report of I73 (other peripheral vascular diseases),icd10_i73,3 +131388-0.0,Source of report of I74 (arterial embolism and thrombosis),icd10_i74,3 +131390-0.0,Source of report of I77 (other disorders of arteries and arterioles),icd10_i77,3 +131392-0.0,Source of report of I78 (diseases of capillaries),icd10_i78,3 +131394-0.0,"Source of report of I79 (disorders of arteries, arterioles and capillaries in diseases classified elsewhere)",icd10_i79,3 +131396-0.0,Source of report of I80 (phlebitis and thrombophlebitis),icd10_i80,3 +131398-0.0,Source of report of I81 (portal vein thrombosis),icd10_i81,3 +131400-0.0,Source of report of I82 (other venous embolism and thrombosis),icd10_i82,3 +131402-0.0,Source of report of I83 (varicose veins of lower extremities),icd10_i83,3 +131404-0.0,Source of report of I84 (haemorrhoids),icd10_i84,3 +131406-0.0,Source of report of I85 (oesophageal varices),icd10_i85,3 +131408-0.0,Source of report of I86 (varicose veins of other sites),icd10_i86,3 +131410-0.0,Source of report of I87 (other disorders of veins),icd10_i87,3 +131412-0.0,Source of report of I88 (nonspecific lymphadenitis),icd10_i88,3 +131414-0.0,Source of report of I89 (other non-infective disorders of lymphatic vessels and lymph nodes),icd10_i89,3 +131416-0.0,Source of report of I95 (hypotension),icd10_i95,3 +131418-0.0,"Source of report of I97 (postprocedural disorders of circulatory system, not elsewhere classified)",icd10_i97,3 +131420-0.0,Source of report of I98 (other disorders of circulatory system in diseases classified elsewhere),icd10_i98,3 +131422-0.0,Source of report of I99 (other and unspecified disorders of circulatory system),icd10_i99,3 +131424-0.0,Source of report of J00 (acute nasopharyngitis [common cold]),icd10_j00,3 +131426-0.0,Source of report of J01 (acute sinusitis),icd10_j01,3 +131428-0.0,Source of report of J02 (acute pharyngitis),icd10_j02,3 +131430-0.0,Source of report of J03 (acute tonsillitis),icd10_j03,3 +131432-0.0,Source of report of J04 (acute laryngitis and tracheitis),icd10_j04,3 +131434-0.0,Source of report of J05 (acute obstructive laryngitis [croup] and epiglottitis),icd10_j05,3 +131436-0.0,Source of report of J06 (acute upper respiratory infections of multiple and unspecified sites),icd10_j06,3 +131438-0.0,Source of report of J09 (influenza due to certain identified influenza virus),icd10_j09,3 +131440-0.0,Source of report of J10 (influenza due to identified influenza virus),icd10_j10,3 +131442-0.0,"Source of report of J11 (influenza, virus not identified)",icd10_j11,3 +131444-0.0,"Source of report of J12 (viral pneumonia, not elsewhere classified)",icd10_j12,3 +131446-0.0,Source of report of J13 (pneumonia due to streptococcus pneumoniae),icd10_j13,3 +131448-0.0,Source of report of J14 (pneumonia due to haemophilus influenzae),icd10_j14,3 +131450-0.0,"Source of report of J15 (bacterial pneumonia, not elsewhere classified)",icd10_j15,3 +131452-0.0,"Source of report of J16 (pneumonia due to other infectious organisms, not elsewhere classified)",icd10_j16,3 +131454-0.0,Source of report of J17 (pneumonia in diseases classified elsewhere),icd10_j17,3 +131456-0.0,"Source of report of J18 (pneumonia, organism unspecified)",icd10_j18,3 +131458-0.0,Source of report of J20 (acute bronchitis),icd10_j20,3 +131460-0.0,Source of report of J21 (acute bronchiolitis),icd10_j21,3 +131462-0.0,Source of report of J22 (unspecified acute lower respiratory infection),icd10_j22,3 +131464-0.0,Source of report of J30 (vasomotor and allergic rhinitis),icd10_j30,3 +131466-0.0,"Source of report of J31 (chronic rhinitis, nasopharyngitis and pharyngitis)",icd10_j31,3 +131468-0.0,Source of report of J32 (chronic sinusitis),icd10_j32,3 +131470-0.0,Source of report of J33 (nasal polyp),icd10_j33,3 +131472-0.0,Source of report of J34 (other disorders of nose and nasal sinuses),icd10_j34,3 +131474-0.0,Source of report of J35 (chronic diseases of tonsils and adenoids),icd10_j35,3 +131476-0.0,Source of report of J36 (peritonsillar abscess),icd10_j36,3 +131478-0.0,Source of report of J37 (chronic laryngitis and laryngotracheitis),icd10_j37,3 +131480-0.0,"Source of report of J38 (diseases of vocal cords and larynx, not elsewhere classified)",icd10_j38,3 +131482-0.0,Source of report of J39 (other diseases of upper respiratory tract),icd10_j39,3 +131484-0.0,"Source of report of J40 (bronchitis, not specified as acute or chronic)",icd10_j40,3 +131486-0.0,Source of report of J41 (simple and mucopurulent chronic bronchitis),icd10_j41,3 +131488-0.0,Source of report of J42 (unspecified chronic bronchitis),icd10_j42,3 +131490-0.0,Source of report of J43 (emphysema),icd10_j43,3 +131492-0.0,Source of report of J44 (other chronic obstructive pulmonary disease),icd10_j44,3 +131494-0.0,Source of report of J45 (asthma),icd10_j45,3 +131496-0.0,Source of report of J46 (status asthmaticus),icd10_j46,3 +131498-0.0,Source of report of J47 (bronchiectasis),icd10_j47,3 +131500-0.0,Source of report of J60 (coalworker's pneumoconiosis),icd10_j60,3 +131502-0.0,Source of report of J61 (pneumoconiosis due to asbestos and other mineral fibres),icd10_j61,3 +131504-0.0,Source of report of J62 (pneumoconiosis due to dust containing silica),icd10_j62,3 +131506-0.0,Source of report of J63 (pneumoconiosis due to other inorganic dusts),icd10_j63,3 +131508-0.0,Source of report of J64 (unspecified pneumoconiosis),icd10_j64,3 +131512-0.0,Source of report of J66 (airway disease due to specific organic dust),icd10_j66,3 +131514-0.0,Source of report of J67 (hypersensitivity pneumonitis due to organic dust),icd10_j67,3 +131516-0.0,"Source of report of J68 (respiratory conditions due to inhalation of chemicals, gases, fumes and vapours)",icd10_j68,3 +131518-0.0,Source of report of J69 (pneumonitis due to solids and liquids),icd10_j69,3 +131520-0.0,Source of report of J70 (respiratory conditions due to other external agents),icd10_j70,3 +131522-0.0,Source of report of J80 (adult respiratory distress syndrome),icd10_j80,3 +131524-0.0,Source of report of J81 (pulmonary oedema),icd10_j81,3 +131526-0.0,"Source of report of J82 (pulmonary eosinophilia, not elsewhere classified)",icd10_j82,3 +131528-0.0,Source of report of J84 (other interstitial pulmonary diseases),icd10_j84,3 +131530-0.0,Source of report of J85 (abscess of lung and mediastinum),icd10_j85,3 +131532-0.0,Source of report of J86 (pyothorax),icd10_j86,3 +131534-0.0,"Source of report of J90 (pleural effusion, not elsewhere classified)",icd10_j90,3 +131536-0.0,Source of report of J91 (pleural effusion in conditions classified elsewhere),icd10_j91,3 +131538-0.0,Source of report of J92 (pleural plaque),icd10_j92,3 +131540-0.0,Source of report of J93 (pneumothorax),icd10_j93,3 +131542-0.0,Source of report of J94 (other pleural conditions),icd10_j94,3 +131544-0.0,"Source of report of J95 (postprocedural respiratory disorders, not elsewhere classified)",icd10_j95,3 +131546-0.0,"Source of report of J96 (respiratory failure, not elsewhere classified)",icd10_j96,3 +131548-0.0,Source of report of J98 (other respiratory disorders),icd10_j98,3 +131550-0.0,Source of report of J99 (respiratory disorders in diseases classified elsewhere),icd10_j99,3 +131552-0.0,Source of report of K00 (disorders of tooth development and eruption),icd10_k00,3 +131554-0.0,Source of report of K01 (embedded and impacted teeth),icd10_k01,3 +131556-0.0,Source of report of K02 (dental caries),icd10_k02,3 +131558-0.0,Source of report of K03 (other diseases of hard tissues of teeth),icd10_k03,3 +131560-0.0,Source of report of K04 (diseases of pulp and periapical tissues),icd10_k04,3 +131562-0.0,Source of report of K05 (gingivitis and periodontal diseases),icd10_k05,3 +131564-0.0,Source of report of K06 (other disorders of gingiva and edentulous alveolar ridge),icd10_k06,3 +131566-0.0,Source of report of K07 (dentofacial anomalies [including malocclusion]),icd10_k07,3 +131568-0.0,Source of report of K08 (other disorders of teeth and supporting structures),icd10_k08,3 +131570-0.0,"Source of report of K09 (cysts of oral region, not elsewhere classified)",icd10_k09,3 +131572-0.0,Source of report of K10 (other diseases of jaws),icd10_k10,3 +131574-0.0,Source of report of K11 (diseases of salivary glands),icd10_k11,3 +131576-0.0,Source of report of K12 (stomatitis and related lesions),icd10_k12,3 +131578-0.0,Source of report of K13 (other diseases of lip and oral mucosa),icd10_k13,3 +131580-0.0,Source of report of K14 (diseases of tongue),icd10_k14,3 +131582-0.0,Source of report of K20 (oesophagitis),icd10_k20,3 +131584-0.0,Source of report of K21 (gastro-oesophageal reflux disease),icd10_k21,3 +131586-0.0,Source of report of K22 (other diseases of oesophagus),icd10_k22,3 +131588-0.0,Source of report of K23 (disorders of oesophagus in diseases classified elsewhere),icd10_k23,3 +131590-0.0,Source of report of K25 (gastric ulcer),icd10_k25,3 +131592-0.0,Source of report of K26 (duodenal ulcer),icd10_k26,3 +131594-0.0,"Source of report of K27 (peptic ulcer, site unspecified)",icd10_k27,3 +131596-0.0,Source of report of K28 (gastrojejunal ulcer),icd10_k28,3 +131598-0.0,Source of report of K29 (gastritis and duodenitis),icd10_k29,3 +131600-0.0,Source of report of K30 (dyspepsia),icd10_k30,3 +131602-0.0,Source of report of K31 (other diseases of stomach and duodenum),icd10_k31,3 +131604-0.0,Source of report of K35 (acute appendicitis),icd10_k35,3 +131606-0.0,Source of report of K36 (other appendicitis),icd10_k36,3 +131608-0.0,Source of report of K37 (unspecified appendicitis),icd10_k37,3 +131610-0.0,Source of report of K38 (other diseases of appendix),icd10_k38,3 +131612-0.0,Source of report of K40 (inguinal hernia),icd10_k40,3 +131614-0.0,Source of report of K41 (femoral hernia),icd10_k41,3 +131616-0.0,Source of report of K42 (umbilical hernia),icd10_k42,3 +131618-0.0,Source of report of K43 (ventral hernia),icd10_k43,3 +131620-0.0,Source of report of K44 (diaphragmatic hernia),icd10_k44,3 +131622-0.0,Source of report of K45 (other abdominal hernia),icd10_k45,3 +131624-0.0,Source of report of K46 (unspecified abdominal hernia),icd10_k46,3 +131626-0.0,Source of report of K50 (crohn's disease [regional enteritis]),icd10_k50,3 +131628-0.0,Source of report of K51 (ulcerative colitis),icd10_k51,3 +131630-0.0,Source of report of K52 (other non-infective gastro-enteritis and colitis),icd10_k52,3 +131632-0.0,Source of report of K55 (vascular disorders of intestine),icd10_k55,3 +131634-0.0,Source of report of K56 (paralytic ileus and intestinal obstruction without hernia),icd10_k56,3 +131636-0.0,Source of report of K57 (diverticular disease of intestine),icd10_k57,3 +131638-0.0,Source of report of K58 (irritable bowel syndrome),icd10_k58,3 +131640-0.0,Source of report of K59 (other functional intestinal disorders),icd10_k59,3 +131642-0.0,Source of report of K60 (fissure and fistula of anal and rectal regions),icd10_k60,3 +131644-0.0,Source of report of K61 (abscess of anal and rectal regions),icd10_k61,3 +131646-0.0,Source of report of K62 (other diseases of anus and rectum),icd10_k62,3 +131648-0.0,Source of report of K63 (other diseases of intestine),icd10_k63,3 +131650-0.0,Source of report of K64 (haemorrhoids and perianal venous thrombosis),icd10_k64,3 +131652-0.0,Source of report of K65 (peritonitis),icd10_k65,3 +131654-0.0,Source of report of K66 (other disorders of peritoneum),icd10_k66,3 +131656-0.0,Source of report of K67 (disorders of peritoneum in infectious diseases classified elsewhere),icd10_k67,3 +131658-0.0,Source of report of K70 (alcoholic liver disease),icd10_k70,3 +131660-0.0,Source of report of K71 (toxic liver disease),icd10_k71,3 +131662-0.0,"Source of report of K72 (hepatic failure, not elsewhere classified)",icd10_k72,3 +131664-0.0,"Source of report of K73 (chronic hepatitis, not elsewhere classified)",icd10_k73,3 +131666-0.0,Source of report of K74 (fibrosis and cirrhosis of liver),icd10_k74,3 +131668-0.0,Source of report of K75 (other inflammatory liver diseases),icd10_k75,3 +131670-0.0,Source of report of K76 (other diseases of liver),icd10_k76,3 +131672-0.0,Source of report of K77 (liver disorders in diseases classified elsewhere),icd10_k77,3 +131674-0.0,Source of report of K80 (cholelithiasis),icd10_k80,3 +131676-0.0,Source of report of K81 (cholecystitis),icd10_k81,3 +131678-0.0,Source of report of K82 (other diseases of gallbladder),icd10_k82,3 +131680-0.0,Source of report of K83 (other diseases of biliary tract),icd10_k83,3 +131682-0.0,Source of report of K85 (acute pancreatitis),icd10_k85,3 +131684-0.0,Source of report of K86 (other diseases of pancreas),icd10_k86,3 +131686-0.0,"Source of report of K87 (disorders of gallbladder, biliary tract and pancreas in diseases classified elsewhere)",icd10_k87,3 +131688-0.0,Source of report of K90 (intestinal malabsorption),icd10_k90,3 +131690-0.0,"Source of report of K91 (postprocedural disorders of digestive system, not elsewhere classified)",icd10_k91,3 +131692-0.0,Source of report of K92 (other diseases of digestive system),icd10_k92,3 +131694-0.0,Source of report of K93 (disorders of other digestive organs in diseases classified elsewhere),icd10_k93,3 +131696-0.0,Source of report of L00 (staphylococcal scalded skin syndrome),icd10_l00,3 +131698-0.0,Source of report of L01 (impetigo),icd10_l01,3 +131700-0.0,"Source of report of L02 (cutaneous abscess, furuncle and carbuncle)",icd10_l02,3 +131702-0.0,Source of report of L03 (cellulitis),icd10_l03,3 +131704-0.0,Source of report of L04 (acute lymphadenitis),icd10_l04,3 +131706-0.0,Source of report of L05 (pilonidal cyst),icd10_l05,3 +131708-0.0,Source of report of L08 (other local infections of skin and subcutaneous tissue),icd10_l08,3 +131710-0.0,Source of report of L10 (pemphigus),icd10_l10,3 +131712-0.0,Source of report of L11 (other acantholytic disorders),icd10_l11,3 +131714-0.0,Source of report of L12 (pemphigoid),icd10_l12,3 +131716-0.0,Source of report of L13 (other bullous disorders),icd10_l13,3 +131718-0.0,Source of report of L14 (bullous disorders in diseases classified elsewhere),icd10_l14,3 +131720-0.0,Source of report of L20 (atopic dermatitis),icd10_l20,3 +131722-0.0,Source of report of L21 (seborrhoeic dermatitis),icd10_l21,3 +131724-0.0,Source of report of L22 (diaper [napkin] dermatitis),icd10_l22,3 +131726-0.0,Source of report of L23 (allergic contact dermatitis),icd10_l23,3 +131728-0.0,Source of report of L24 (irritant contact dermatitis),icd10_l24,3 +131730-0.0,Source of report of L25 (unspecified contact dermatitis),icd10_l25,3 +131732-0.0,Source of report of L26 (exfoliative dermatitis),icd10_l26,3 +131734-0.0,Source of report of L27 (dermatitis due to substances taken internally),icd10_l27,3 +131736-0.0,Source of report of L28 (lichen simplex chronicus and prurigo),icd10_l28,3 +131738-0.0,Source of report of L29 (pruritus),icd10_l29,3 +131740-0.0,Source of report of L30 (other dermatitis),icd10_l30,3 +131742-0.0,Source of report of L40 (psoriasis),icd10_l40,3 +131744-0.0,Source of report of L41 (parapsoriasis),icd10_l41,3 +131746-0.0,Source of report of L42 (pityriasis rosea),icd10_l42,3 +131748-0.0,Source of report of L43 (lichen planus),icd10_l43,3 +131750-0.0,Source of report of L44 (other papulosquamous disorders),icd10_l44,3 +131754-0.0,Source of report of L50 (urticaria),icd10_l50,3 +131756-0.0,Source of report of L51 (erythema multiforme),icd10_l51,3 +131758-0.0,Source of report of L52 (erythema nodosum),icd10_l52,3 +131760-0.0,Source of report of L53 (other erythematous conditions),icd10_l53,3 +131762-0.0,Source of report of L54 (erythema in diseases classified elsewhere),icd10_l54,3 +131764-0.0,Source of report of L55 (sunburn),icd10_l55,3 +131766-0.0,Source of report of L56 (other acute skin changes due to ultraviolet radiation),icd10_l56,3 +131768-0.0,Source of report of L57 (skin changes due to chronic exposure to nonionising radiation),icd10_l57,3 +131770-0.0,Source of report of L58 (radiodermatitis),icd10_l58,3 +131772-0.0,Source of report of L59 (other disorders of skin and subcutaneous tissue related to radiation),icd10_l59,3 +131774-0.0,Source of report of L60 (nail disorders),icd10_l60,3 +131776-0.0,Source of report of L62 (nail disorders in diseases classified elsewhere),icd10_l62,3 +131778-0.0,Source of report of L63 (alopecia areata),icd10_l63,3 +131780-0.0,Source of report of L64 (androgenic alopecia),icd10_l64,3 +131782-0.0,Source of report of L65 (other nonscarring hair loss),icd10_l65,3 +131784-0.0,Source of report of L66 (cicatricial alopecia [scarring hair loss]),icd10_l66,3 +131786-0.0,Source of report of L67 (hair colour and hair shaft abnormalities),icd10_l67,3 +131788-0.0,Source of report of L68 (hypertrichosis),icd10_l68,3 +131790-0.0,Source of report of L70 (acne),icd10_l70,3 +131792-0.0,Source of report of L71 (rosacea),icd10_l71,3 +131794-0.0,Source of report of L72 (follicular cysts of skin and subcutaneous tissue),icd10_l72,3 +131796-0.0,Source of report of L73 (other follicular disorders),icd10_l73,3 +131798-0.0,Source of report of L74 (eccrine sweat disorders),icd10_l74,3 +131800-0.0,Source of report of L75 (apocrine sweat disorders),icd10_l75,3 +131802-0.0,Source of report of L80 (vitiligo),icd10_l80,3 +131804-0.0,Source of report of L81 (other disorders of pigmentation),icd10_l81,3 +131806-0.0,Source of report of L82 (seborrhoeic keratosis),icd10_l82,3 +131808-0.0,Source of report of L83 (acanthosis nigricans),icd10_l83,3 +131810-0.0,Source of report of L84 (corns and callosities),icd10_l84,3 +131812-0.0,Source of report of L85 (other epidermal thickening),icd10_l85,3 +131814-0.0,Source of report of L86 (keratoderma in diseases classified elsewhere),icd10_l86,3 +131816-0.0,Source of report of L87 (transepidermal elimination disorders),icd10_l87,3 +131818-0.0,Source of report of L88 (pyoderma gangrenosum),icd10_l88,3 +131820-0.0,Source of report of L89 (decubitus ulcer),icd10_l89,3 +131822-0.0,Source of report of L90 (atrophic disorders of skin),icd10_l90,3 +131824-0.0,Source of report of L91 (hypertrophic disorders of skin),icd10_l91,3 +131826-0.0,Source of report of L92 (granulomatous disorders of skin and subcutaneous tissue),icd10_l92,3 +131828-0.0,Source of report of L93 (lupus erythematosus),icd10_l93,3 +131830-0.0,Source of report of L94 (other localised connective tissue disorders),icd10_l94,3 +131832-0.0,"Source of report of L95 (vasculitis limited to skin, not elsewhere classified)",icd10_l95,3 +131834-0.0,"Source of report of L97 (ulcer of lower limb, not elsewhere classified)",icd10_l97,3 +131836-0.0,"Source of report of L98 (other disorders of skin and subcutaneous tissue, not elsewhere classified)",icd10_l98,3 +131838-0.0,Source of report of L99 (other disorders of skin and subcutaneous tissue in diseases classified elsewhere),icd10_l99,3 +131840-0.0,Source of report of M00 (pyogenic arthritis),icd10_m00,3 +131842-0.0,Source of report of M01 (direct infections of joint in infectious and parasitic diseases classified elsewhere),icd10_m01,3 +131844-0.0,Source of report of M02 (reactive arthropathies),icd10_m02,3 +131846-0.0,Source of report of M03 (postinfective and reactive arthropathies in diseases classified elsewhere),icd10_m03,3 +131848-0.0,Source of report of M05 (seropositive rheumatoid arthritis),icd10_m05,3 +131850-0.0,Source of report of M06 (other rheumatoid arthritis),icd10_m06,3 +131852-0.0,Source of report of M07 (psoriatic and enteropathic arthropathies),icd10_m07,3 +131854-0.0,Source of report of M08 (juvenile arthritis),icd10_m08,3 +131856-0.0,Source of report of M09 (juvenile arthritis in diseases classified elsewhere),icd10_m09,3 +131858-0.0,Source of report of M10 (gout),icd10_m10,3 +131860-0.0,Source of report of M11 (other crystal arthropathies),icd10_m11,3 +131862-0.0,Source of report of M12 (other specific arthropathies),icd10_m12,3 +131864-0.0,Source of report of M13 (other arthritis),icd10_m13,3 +131866-0.0,Source of report of M14 (arthropathies in other diseases classified elsewhere),icd10_m14,3 +131868-0.0,Source of report of M15 (polyarthrosis),icd10_m15,3 +131870-0.0,Source of report of M16 (coxarthrosis [arthrosis of hip]),icd10_m16,3 +131872-0.0,Source of report of M17 (gonarthrosis [arthrosis of knee]),icd10_m17,3 +131874-0.0,Source of report of M18 (arthrosis of first carpometacarpal joint),icd10_m18,3 +131876-0.0,Source of report of M19 (other arthrosis),icd10_m19,3 +131878-0.0,Source of report of M20 (acquired deformities of fingers and toes),icd10_m20,3 +131880-0.0,Source of report of M21 (other acquired deformities of limbs),icd10_m21,3 +131882-0.0,Source of report of M22 (disorders of patella),icd10_m22,3 +131884-0.0,Source of report of M23 (internal derangement of knee),icd10_m23,3 +131886-0.0,Source of report of M24 (other specific joint derangements),icd10_m24,3 +131888-0.0,"Source of report of M25 (other joint disorders, not elsewhere classified)",icd10_m25,3 +131890-0.0,Source of report of M30 (polyarteritis nodosa and related conditions),icd10_m30,3 +131892-0.0,Source of report of M31 (other necrotising vasculopathies),icd10_m31,3 +131894-0.0,Source of report of M32 (systemic lupus erythematosus),icd10_m32,3 +131896-0.0,Source of report of M33 (dermatopolymyositis),icd10_m33,3 +131898-0.0,Source of report of M34 (systemic sclerosis),icd10_m34,3 +131900-0.0,Source of report of M35 (other systemic involvement of connective tissue),icd10_m35,3 +131902-0.0,Source of report of M36 (systemic disorders of connective tissue in diseases classified elsewhere),icd10_m36,3 +131904-0.0,Source of report of M40 (kyphosis and lordosis),icd10_m40,3 +131906-0.0,Source of report of M41 (scoliosis),icd10_m41,3 +131908-0.0,Source of report of M42 (spinal osteochondrosis),icd10_m42,3 +131910-0.0,Source of report of M43 (other deforming dorsopathies),icd10_m43,3 +131912-0.0,Source of report of M45 (ankylosing spondylitis),icd10_m45,3 +131914-0.0,Source of report of M46 (other inflammatory spondylopathies),icd10_m46,3 +131916-0.0,Source of report of M47 (spondylosis),icd10_m47,3 +131918-0.0,Source of report of M48 (other spondylopathies),icd10_m48,3 +131920-0.0,Source of report of M49 (spondylopathies in diseases classified elsewhere),icd10_m49,3 +131922-0.0,Source of report of M50 (cervical disk disorders),icd10_m50,3 +131924-0.0,Source of report of M51 (other intervertebral disk disorders),icd10_m51,3 +131926-0.0,"Source of report of M53 (other dorsopathies, not elsewhere classified)",icd10_m53,3 +131928-0.0,Source of report of M54 (dorsalgia),icd10_m54,3 +131930-0.0,Source of report of M60 (myositis),icd10_m60,3 +131932-0.0,Source of report of M61 (calcification and ossification of muscle),icd10_m61,3 +131934-0.0,Source of report of M62 (other disorders of muscle),icd10_m62,3 +131936-0.0,Source of report of M63 (disorders of muscle in diseases classified elsewhere),icd10_m63,3 +131938-0.0,Source of report of M65 (synovitis and tenosynovitis),icd10_m65,3 +131940-0.0,Source of report of M66 (spontaneous rupture of synovium and tendon),icd10_m66,3 +131942-0.0,Source of report of M67 (other disorders of synovium and tendon),icd10_m67,3 +131944-0.0,Source of report of M68 (disorders of synovium and tendon in diseases classified elsewhere),icd10_m68,3 +131946-0.0,"Source of report of M70 (soft tissue disorders related to use, overuse and pressure)",icd10_m70,3 +131948-0.0,Source of report of M71 (other bursopathies),icd10_m71,3 +131950-0.0,Source of report of M72 (fibroblastic disorders),icd10_m72,3 +131952-0.0,Source of report of M73 (soft tissue disorders in diseases classified elsewhere),icd10_m73,3 +131954-0.0,Source of report of M75 (shoulder lesions),icd10_m75,3 +131956-0.0,"Source of report of M76 (enthesopathies of lower limb, excluding foot)",icd10_m76,3 +131958-0.0,Source of report of M77 (other enthesopathies),icd10_m77,3 +131960-0.0,"Source of report of M79 (other soft tissue disorders, not elsewhere classified)",icd10_m79,3 +131962-0.0,Source of report of M80 (osteoporosis with pathological fracture),icd10_m80,3 +131964-0.0,Source of report of M81 (osteoporosis without pathological fracture),icd10_m81,3 +131966-0.0,Source of report of M82 (osteoporosis in diseases classified elsewhere),icd10_m82,3 +131968-0.0,Source of report of M83 (adult osteomalacia),icd10_m83,3 +131970-0.0,Source of report of M84 (disorders of continuity of bone),icd10_m84,3 +131972-0.0,Source of report of M85 (other disorders of bone density and structure),icd10_m85,3 +131974-0.0,Source of report of M86 (osteomyelitis),icd10_m86,3 +131976-0.0,Source of report of M87 (osteonecrosis),icd10_m87,3 +131978-0.0,Source of report of M88 (paget's disease of bone [osteitis deformans]),icd10_m88,3 +131980-0.0,Source of report of M89 (other disorders of bone),icd10_m89,3 +131982-0.0,Source of report of M90 (osteopathies in diseases classified elsewhere),icd10_m90,3 +131984-0.0,Source of report of M91 (juvenile osteochondrosis of hip and pelvis),icd10_m91,3 +131986-0.0,Source of report of M92 (other juvenile osteochondrosis),icd10_m92,3 +131988-0.0,Source of report of M93 (other osteochondropathies),icd10_m93,3 +131990-0.0,Source of report of M94 (other disorders of cartilage),icd10_m94,3 +131992-0.0,Source of report of M95 (other acquired deformities of musculoskeletal system and connective tissue),icd10_m95,3 +131994-0.0,"Source of report of M96 (postprocedural musculoskeletal disorders, not elsewhere classified)",icd10_m96,3 +131996-0.0,"Source of report of M99 (biomechanical lesions, not elsewhere classified)",icd10_m99,3 +131998-0.0,Source of report of N00 (acute nephritic syndrome),icd10_n00,3 +132000-0.0,Source of report of N01 (rapidly progressive nephritic syndrome),icd10_n01,3 +132002-0.0,Source of report of N02 (recurrent and persistent haematuria),icd10_n02,3 +132004-0.0,Source of report of N03 (chronic nephritic syndrome),icd10_n03,3 +132006-0.0,Source of report of N04 (nephrotic syndrome),icd10_n04,3 +132008-0.0,Source of report of N05 (unspecified nephritic syndrome),icd10_n05,3 +132010-0.0,Source of report of N06 (isolated proteinuria with specified morphological lesion),icd10_n06,3 +132012-0.0,"Source of report of N07 (hereditary nephropathy, not elsewhere classified)",icd10_n07,3 +132014-0.0,Source of report of N08 (glomerular disorders in diseases classified elsewhere),icd10_n08,3 +132016-0.0,Source of report of N10 (acute tubulo-interstitial nephritis),icd10_n10,3 +132018-0.0,Source of report of N11 (chronic tubulo-interstitial nephritis),icd10_n11,3 +132020-0.0,"Source of report of N12 (tubulo-interstitial nephritis, not specified as acute or chronic)",icd10_n12,3 +132022-0.0,Source of report of N13 (obstructive and reflux uropathy),icd10_n13,3 +132024-0.0,Source of report of N14 (drug- and heavy-metal-induced tubulo-interstitial and tubular conditions),icd10_n14,3 +132026-0.0,Source of report of N15 (other renal tubulo-interstitial diseases),icd10_n15,3 +132028-0.0,Source of report of N16 (renal tubulo-interstitial disorders in diseases classified elsewhere),icd10_n16,3 +132030-0.0,Source of report of N17 (acute renal failure),icd10_n17,3 +132032-0.0,Source of report of N18 (chronic renal failure),icd10_n18,3 +132034-0.0,Source of report of N19 (unspecified renal failure),icd10_n19,3 +132036-0.0,Source of report of N20 (calculus of kidney and ureter),icd10_n20,3 +132038-0.0,Source of report of N21 (calculus of lower urinary tract),icd10_n21,3 +132040-0.0,Source of report of N22 (calculus of urinary tract in diseases classified elsewhere),icd10_n22,3 +132042-0.0,Source of report of N23 (unspecified renal colic),icd10_n23,3 +132044-0.0,Source of report of N25 (disorders resulting from impaired renal tubular function),icd10_n25,3 +132046-0.0,Source of report of N26 (unspecified contracted kidney),icd10_n26,3 +132048-0.0,Source of report of N27 (small kidney of unknown cause),icd10_n27,3 +132050-0.0,"Source of report of N28 (other disorders of kidney and ureter, not elsewhere classified)",icd10_n28,3 +132052-0.0,Source of report of N29 (other disorders of kidney and ureter in diseases classified elsewhere),icd10_n29,3 +132054-0.0,Source of report of N30 (cystitis),icd10_n30,3 +132056-0.0,"Source of report of N31 (neuromuscular dysfunction of bladder, not elsewhere classified)",icd10_n31,3 +132058-0.0,Source of report of N32 (other disorders of bladder),icd10_n32,3 +132060-0.0,Source of report of N33 (bladder disorders in diseases classified elsewhere),icd10_n33,3 +132062-0.0,Source of report of N34 (urethritis and urethral syndrome),icd10_n34,3 +132064-0.0,Source of report of N35 (urethral stricture),icd10_n35,3 +132066-0.0,Source of report of N36 (other disorders of urethra),icd10_n36,3 +132068-0.0,Source of report of N37 (urethral disorders in diseases classified elsewhere),icd10_n37,3 +132070-0.0,Source of report of N39 (other disorders of urinary system),icd10_n39,3 +132072-0.0,Source of report of N40 (hyperplasia of prostate),icd10_n40,3 +132074-0.0,Source of report of N41 (inflammatory diseases of prostate),icd10_n41,3 +132076-0.0,Source of report of N42 (other disorders of prostate),icd10_n42,3 +132078-0.0,Source of report of N43 (hydrocele and spermatocele),icd10_n43,3 +132080-0.0,Source of report of N44 (torsion of testis),icd10_n44,3 +132082-0.0,Source of report of N45 (orchitis and epididymitis),icd10_n45,3 +132084-0.0,Source of report of N46 (male infertility),icd10_n46,3 +132086-0.0,"Source of report of N47 (redundant prepuce, phimosis and paraphimosis)",icd10_n47,3 +132088-0.0,Source of report of N48 (other disorders of penis),icd10_n48,3 +132090-0.0,"Source of report of N49 (inflammatory disorders of male genital organs, not elsewhere classified)",icd10_n49,3 +132092-0.0,Source of report of N50 (other disorders of male genital organs),icd10_n50,3 +132094-0.0,Source of report of N51 (disorders of male genital organs in diseases classified elsewhere),icd10_n51,3 +132096-0.0,Source of report of N60 (benign mammary dysplasia),icd10_n60,3 +132098-0.0,Source of report of N61 (inflammatory disorders of breast),icd10_n61,3 +132100-0.0,Source of report of N62 (hypertrophy of breast),icd10_n62,3 +132102-0.0,Source of report of N63 (unspecified lump in breast),icd10_n63,3 +132104-0.0,Source of report of N64 (other disorders of breast),icd10_n64,3 +132106-0.0,Source of report of N70 (salpingitis and oophoritis),icd10_n70,3 +132108-0.0,"Source of report of N71 (inflammatory disease of uterus, except cervix)",icd10_n71,3 +132110-0.0,Source of report of N72 (inflammatory disease of cervix uteri),icd10_n72,3 +132112-0.0,Source of report of N73 (other female pelvic inflammatory diseases),icd10_n73,3 +132114-0.0,Source of report of N74 (female pelvic inflammatory disorders in diseases classified elsewhere),icd10_n74,3 +132116-0.0,Source of report of N75 (diseases of bartholin's gland),icd10_n75,3 +132118-0.0,Source of report of N76 (other inflammation of vagina and vulva),icd10_n76,3 +132120-0.0,Source of report of N77 (vulvovaginal ulceration and inflammation in diseases classified elsewhere),icd10_n77,3 +132122-0.0,Source of report of N80 (endometriosis),icd10_n80,3 +132124-0.0,Source of report of N81 (female genital prolapse),icd10_n81,3 +132126-0.0,Source of report of N82 (fistulae involving female genital tract),icd10_n82,3 +132128-0.0,"Source of report of N83 (noninflammatory disorders of ovary, fallopian tube and broad ligament)",icd10_n83,3 +132130-0.0,Source of report of N84 (polyp of female genital tract),icd10_n84,3 +132132-0.0,"Source of report of N85 (other noninflammatory disorders of uterus, except cervix)",icd10_n85,3 +132134-0.0,Source of report of N86 (erosion and ectropion of cervix uteri),icd10_n86,3 +132136-0.0,Source of report of N87 (dysplasia of cervix uteri),icd10_n87,3 +132138-0.0,Source of report of N88 (other noninflammatory disorders of cervix uteri),icd10_n88,3 +132140-0.0,Source of report of N89 (other noninflammatory disorders of vagina),icd10_n89,3 +132142-0.0,Source of report of N90 (other noninflammatory disorders of vulva and perineum),icd10_n90,3 +132144-0.0,"Source of report of N91 (absent, scanty and rare menstruation)",icd10_n91,3 +132146-0.0,"Source of report of N92 (excessive, frequent and irregular menstruation)",icd10_n92,3 +132148-0.0,Source of report of N93 (other abnormal uterine and vaginal bleeding),icd10_n93,3 +132150-0.0,Source of report of N94 (pain and other conditions associated with female genital organs and menstrual cycle),icd10_n94,3 +132152-0.0,Source of report of N95 (menopausal and other perimenopausal disorders),icd10_n95,3 +132154-0.0,Source of report of N96 (habitual aborter),icd10_n96,3 +132156-0.0,Source of report of N97 (female infertility),icd10_n97,3 +132158-0.0,Source of report of N98 (complications associated with artificial fertilisation),icd10_n98,3 +132160-0.0,"Source of report of N99 (postprocedural disorders of genito-urinary system, not elsewhere classified)",icd10_n99,3 +132162-0.0,Source of report of O00 (ectopic pregnancy),icd10_o00,3 +132164-0.0,Source of report of O01 (hydatidiform mole),icd10_o01,3 +132166-0.0,Source of report of O02 (other abnormal products of conception),icd10_o02,3 +132168-0.0,Source of report of O03 (spontaneous abortion),icd10_o03,3 +132170-0.0,Source of report of O04 (medical abortion),icd10_o04,3 +132172-0.0,Source of report of O05 (other abortion),icd10_o05,3 +132174-0.0,Source of report of O06 (unspecified abortion),icd10_o06,3 +132176-0.0,Source of report of O07 (failed attempted abortion),icd10_o07,3 +132178-0.0,Source of report of O08 (complications following abortion and ectopic and molar pregnancy),icd10_o08,3 +132180-0.0,"Source of report of O10 (pre-existing hypertension complicating pregnancy, childbirth and the puerperium)",icd10_o10,3 +132182-0.0,Source of report of O11 (pre-existing hypertensive disorder with superimposed proteinuria),icd10_o11,3 +132184-0.0,Source of report of O12 (gestational [pregnancy-induced] oedema and proteinuria without hypertension),icd10_o12,3 +132186-0.0,Source of report of O13 (gestational [pregnancy-induced] hypertension without significant proteinuria),icd10_o13,3 +132188-0.0,Source of report of O14 (gestational [pregnancy-induced] hypertension with significant proteinuria),icd10_o14,3 +132190-0.0,Source of report of O15 (eclampsia),icd10_o15,3 +132192-0.0,Source of report of O16 (unspecified maternal hypertension),icd10_o16,3 +132194-0.0,Source of report of O20 (haemorrhage in early pregnancy),icd10_o20,3 +132196-0.0,Source of report of O21 (excessive vomiting in pregnancy),icd10_o21,3 +132198-0.0,Source of report of O22 (venous complications in pregnancy),icd10_o22,3 +132200-0.0,Source of report of O23 (infections of genito-urinary tract in pregnancy),icd10_o23,3 +132202-0.0,Source of report of O24 (diabetes mellitus in pregnancy),icd10_o24,3 +132204-0.0,Source of report of O25 (malnutrition in pregnancy),icd10_o25,3 +132206-0.0,Source of report of O26 (maternal care for other conditions predominantly related to pregnancy),icd10_o26,3 +132208-0.0,Source of report of O28 (abnormal findings on antenatal screening of mother),icd10_o28,3 +132210-0.0,Source of report of O29 (complications of anaesthesia during pregnancy),icd10_o29,3 +132212-0.0,Source of report of O30 (multiple gestation),icd10_o30,3 +132214-0.0,Source of report of O31 (complications specific to multiple gestation),icd10_o31,3 +132216-0.0,Source of report of O32 (maternal care for known or suspected malpresentation of foetus),icd10_o32,3 +132218-0.0,Source of report of O33 (maternal care for known or suspected disproportion),icd10_o33,3 +132220-0.0,Source of report of O34 (maternal care for known or suspected abnormality of pelvic organs),icd10_o34,3 +132222-0.0,Source of report of O35 (maternal care for known or suspected foetal abnormality and damage),icd10_o35,3 +132224-0.0,Source of report of O36 (maternal care for other known or suspected foetal problems),icd10_o36,3 +132226-0.0,Source of report of O40 (polyhydramnios),icd10_o40,3 +132228-0.0,Source of report of O41 (other disorders of amniotic fluid and membranes),icd10_o41,3 +132230-0.0,Source of report of O42 (premature rupture of membranes),icd10_o42,3 +132232-0.0,Source of report of O43 (placental disorders),icd10_o43,3 +132234-0.0,Source of report of O44 (placenta praevia),icd10_o44,3 +132236-0.0,Source of report of O45 (premature separation of placenta [abruptio placentae]),icd10_o45,3 +132238-0.0,"Source of report of O46 (antepartum haemorrhage, not elsewhere classified)",icd10_o46,3 +132240-0.0,Source of report of O47 (false labour),icd10_o47,3 +132242-0.0,Source of report of O48 (prolonged pregnancy),icd10_o48,3 +132244-0.0,Source of report of O60 (preterm delivery),icd10_o60,3 +132246-0.0,Source of report of O61 (failed induction of labour),icd10_o61,3 +132248-0.0,Source of report of O62 (abnormalities of forces of labour),icd10_o62,3 +132250-0.0,Source of report of O63 (long labour),icd10_o63,3 +132252-0.0,Source of report of O64 (obstructed labour due to malposition and malpresentation of foetus),icd10_o64,3 +132254-0.0,Source of report of O65 (obstructed labour due to maternal pelvic abnormality),icd10_o65,3 +132256-0.0,Source of report of O66 (other obstructed labour),icd10_o66,3 +132258-0.0,"Source of report of O67 (labour and delivery complicated by intrapartum haemorrhage, not elsewhere classified)",icd10_o67,3 +132260-0.0,Source of report of O68 (labour and delivery complicated by foetal stress [distress]),icd10_o68,3 +132262-0.0,Source of report of O69 (labour and delivery complicated by umbilical cord complications),icd10_o69,3 +132264-0.0,Source of report of O70 (perineal laceration during delivery),icd10_o70,3 +132266-0.0,Source of report of O71 (other obstetric trauma),icd10_o71,3 +132268-0.0,Source of report of O72 (postpartum haemorrhage),icd10_o72,3 +132270-0.0,"Source of report of O73 (retained placenta and membranes, without haemorrhage)",icd10_o73,3 +132272-0.0,Source of report of O74 (complications of anaesthesia during labour and delivery),icd10_o74,3 +132274-0.0,"Source of report of O75 (other complications of labour and delivery, not elsewhere classified)",icd10_o75,3 +132276-0.0,Source of report of O80 (single spontaneous delivery),icd10_o80,3 +132278-0.0,Source of report of O81 (single delivery by forceps and vacuum extractor),icd10_o81,3 +132280-0.0,Source of report of O82 (single delivery by caesarean section),icd10_o82,3 +132282-0.0,Source of report of O83 (other assisted single delivery),icd10_o83,3 +132284-0.0,Source of report of O84 (multiple delivery),icd10_o84,3 +132286-0.0,Source of report of O85 (puerperal sepsis),icd10_o85,3 +132288-0.0,Source of report of O86 (other puerperal infections),icd10_o86,3 +132290-0.0,Source of report of O87 (venous complications in the puerperium),icd10_o87,3 +132292-0.0,Source of report of O88 (obstetric embolism),icd10_o88,3 +132294-0.0,Source of report of O89 (complications of anaesthesia during the puerperium),icd10_o89,3 +132296-0.0,"Source of report of O90 (complications of the puerperium, not elsewhere classified)",icd10_o90,3 +132298-0.0,Source of report of O91 (infections of breast associated with childbirth),icd10_o91,3 +132300-0.0,Source of report of O92 (other disorders of breast and lactation associated with childbirth),icd10_o92,3 +132302-0.0,"Source of report of O94 (sequelae of complication of pregnancy, childbirth and the puerperium)",icd10_o94,3 +132306-0.0,Source of report of O96 (death from any obstetric cause occurring more than 42 days but less than one year after delivery),icd10_o96,3 +132310-0.0,"Source of report of O98 (maternal infectious and parasitic diseases classifiable elsewhere but complicating pregnancy, childbirth and the puerperium)",icd10_o98,3 +132312-0.0,"Source of report of O99 (other maternal diseases classifiable elsewhere but complicating pregnancy, childbirth and the puerperium)",icd10_o99,3 +132314-0.0,Source of report of P00 (foetus and newborn affected by maternal conditions that may be unrelated to present pregnancy),icd10_p00,3 +132318-0.0,"Source of report of P02 (foetus and newborn affected by complications of placenta, cord and membranes)",icd10_p02,3 +132320-0.0,Source of report of P03 (foetus and newborn affected by other complications of labour and delivery),icd10_p03,3 +132322-0.0,Source of report of P04 (foetus and newborn affected by noxious influences transmitted via placenta or breast milk),icd10_p04,3 +132324-0.0,Source of report of P05 (slow foetal growth and foetal malnutrition),icd10_p05,3 +132326-0.0,"Source of report of P07 (disorders related to short gestation and low birth weight, not elsewhere classified)",icd10_p07,3 +132328-0.0,Source of report of P08 (disorders related to long gestation and high birth weight),icd10_p08,3 +132330-0.0,Source of report of P10 (intracranial laceration and haemorrhage due to birth injury),icd10_p10,3 +132332-0.0,Source of report of P11 (other birth injuries to central nervous system),icd10_p11,3 +132334-0.0,Source of report of P12 (birth injury to scalp),icd10_p12,3 +132336-0.0,Source of report of P13 (birth injury to skeleton),icd10_p13,3 +132338-0.0,Source of report of P14 (birth injury to peripheral nervous system),icd10_p14,3 +132340-0.0,Source of report of P15 (other birth injuries),icd10_p15,3 +132342-0.0,Source of report of P20 (intra-uterine hypoxia),icd10_p20,3 +132344-0.0,Source of report of P21 (birth asphyxia),icd10_p21,3 +132346-0.0,Source of report of P22 (respiratory distress of newborn),icd10_p22,3 +132348-0.0,Source of report of P23 (congenital pneumonia),icd10_p23,3 +132350-0.0,Source of report of P24 (neonatal aspiration syndromes),icd10_p24,3 +132352-0.0,Source of report of P25 (interstitial emphysema and related conditions originating in the perinatal period),icd10_p25,3 +132354-0.0,Source of report of P26 (pulmonary haemorrhage originating in the perinatal period),icd10_p26,3 +132356-0.0,Source of report of P27 (chronic respiratory disease originating in the perinatal period),icd10_p27,3 +132358-0.0,Source of report of P28 (other respiratory conditions originating in the perinatal period),icd10_p28,3 +132360-0.0,Source of report of P29 (cardiovascular disorders originating in the perinatal period),icd10_p29,3 +132362-0.0,Source of report of P35 (congenital viral diseases),icd10_p35,3 +132364-0.0,Source of report of P36 (bacterial sepsis of newborn),icd10_p36,3 +132366-0.0,Source of report of P37 (other congenital infectious and parasitic diseases),icd10_p37,3 +132368-0.0,Source of report of P38 (omphalitis of newborn with or without mild haemorrhage),icd10_p38,3 +132370-0.0,Source of report of P39 (other infections specific to the perinatal period),icd10_p39,3 +132372-0.0,Source of report of P50 (foetal blood loss),icd10_p50,3 +132374-0.0,Source of report of P51 (umbilical haemorrhage of newborn),icd10_p51,3 +132376-0.0,Source of report of P52 (intracranial nontraumatic haemorrhage of foetus and newborn),icd10_p52,3 +132378-0.0,Source of report of P53 (haemorrhagic disease of foetus and newborn),icd10_p53,3 +132380-0.0,Source of report of P54 (other neonatal haemorrhages),icd10_p54,3 +132382-0.0,Source of report of P55 (haemolytic disease of foetus and newborn),icd10_p55,3 +132388-0.0,Source of report of P58 (neonatal jaundice due to other excessive haemolysis),icd10_p58,3 +132390-0.0,Source of report of P59 (neonatal jaundice from other and unspecified causes),icd10_p59,3 +132394-0.0,Source of report of P61 (other perinatal haematological disorders),icd10_p61,3 +132396-0.0,Source of report of P70 (transitory disorders of carbohydrate metabolism specific to foetus and newborn),icd10_p70,3 +132398-0.0,Source of report of P71 (transitory neonatal disorders of calcium and magnesium metabolism),icd10_p71,3 +132410-0.0,Source of report of P78 (other perinatal digestive system disorders),icd10_p78,3 +132416-0.0,Source of report of P83 (other conditions of integument specific to foetus and newborn),icd10_p83,3 +132420-0.0,Source of report of P91 (other disturbances of cerebral status of newborn),icd10_p91,3 +132422-0.0,Source of report of P92 (feeding problems of newborn),icd10_p92,3 +132426-0.0,Source of report of P94 (disorders of muscle tone of newborn),icd10_p94,3 +132428-0.0,Source of report of P95 (foetal death of unspecified cause),icd10_p95,3 +132430-0.0,Source of report of P96 (other conditions originating in the perinatal period),icd10_p96,3 +132432-0.0,Source of report of Q00 (anencephaly and similar malformations),icd10_q00,3 +132434-0.0,Source of report of Q01 (encephalocele),icd10_q01,3 +132436-0.0,Source of report of Q02 (microcephaly),icd10_q02,3 +132438-0.0,Source of report of Q03 (congenital hydrocephalus),icd10_q03,3 +132440-0.0,Source of report of Q04 (other congenital malformations of brain),icd10_q04,3 +132442-0.0,Source of report of Q05 (spina bifida),icd10_q05,3 +132444-0.0,Source of report of Q06 (other congenital malformations of spinal cord),icd10_q06,3 +132446-0.0,Source of report of Q07 (other congenital malformations of nervous system),icd10_q07,3 +132448-0.0,"Source of report of Q10 (congenital malformations of eyelid, lachrymal apparatus and orbit)",icd10_q10,3 +132450-0.0,"Source of report of Q11 (anophthalmos, microphthalmos and macrophthalmos)",icd10_q11,3 +132452-0.0,Source of report of Q12 (congenital lens malformations),icd10_q12,3 +132454-0.0,Source of report of Q13 (congenital malformations of anterior segment of eye),icd10_q13,3 +132456-0.0,Source of report of Q14 (congenital malformations of posterior segment of eye),icd10_q14,3 +132458-0.0,Source of report of Q15 (other congenital malformations of eye),icd10_q15,3 +132460-0.0,Source of report of Q16 (congenital malformations of ear causing impairment of hearing),icd10_q16,3 +132462-0.0,Source of report of Q17 (other congenital malformations of ear),icd10_q17,3 +132464-0.0,Source of report of Q18 (other congenital malformations of face and neck),icd10_q18,3 +132466-0.0,Source of report of Q20 (congenital malformations of cardiac chambers and connexions),icd10_q20,3 +132468-0.0,Source of report of Q21 (congenital malformations of cardiac septa),icd10_q21,3 +132470-0.0,Source of report of Q22 (congenital malformations of pulmonary and tricuspid valves),icd10_q22,3 +132472-0.0,Source of report of Q23 (congenital malformations of aortic and mitral valves),icd10_q23,3 +132474-0.0,Source of report of Q24 (other congenital malformations of heart),icd10_q24,3 +132476-0.0,Source of report of Q25 (congenital malformations of great arteries),icd10_q25,3 +132478-0.0,Source of report of Q26 (congenital malformations of great veins),icd10_q26,3 +132480-0.0,Source of report of Q27 (other congenital malformations of peripheral vascular system),icd10_q27,3 +132482-0.0,Source of report of Q28 (other congenital malformations of circulatory system),icd10_q28,3 +132484-0.0,Source of report of Q30 (congenital malformations of nose),icd10_q30,3 +132486-0.0,Source of report of Q31 (congenital malformations of larynx),icd10_q31,3 +132488-0.0,Source of report of Q32 (congenital malformations of trachea and bronchus),icd10_q32,3 +132490-0.0,Source of report of Q33 (congenital malformations of lung),icd10_q33,3 +132492-0.0,Source of report of Q34 (other congenital malformations of respiratory system),icd10_q34,3 +132494-0.0,Source of report of Q35 (cleft palate),icd10_q35,3 +132496-0.0,Source of report of Q36 (cleft lip),icd10_q36,3 +132498-0.0,Source of report of Q37 (cleft palate with cleft lip),icd10_q37,3 +132500-0.0,"Source of report of Q38 (other congenital malformations of tongue, mouth and pharynx)",icd10_q38,3 +132502-0.0,Source of report of Q39 (congenital malformations of oesophagus),icd10_q39,3 +132504-0.0,Source of report of Q40 (other congenital malformations of upper alimentary tract),icd10_q40,3 +132506-0.0,"Source of report of Q41 (congenital absence, atresia and stenosis of small intestine)",icd10_q41,3 +132508-0.0,"Source of report of Q42 (congenital absence, atresia and stenosis of large intestine)",icd10_q42,3 +132510-0.0,Source of report of Q43 (other congenital malformations of intestine),icd10_q43,3 +132512-0.0,"Source of report of Q44 (congenital malformations of gallbladder, bile ducts and liver)",icd10_q44,3 +132514-0.0,Source of report of Q45 (other congenital malformations of digestive system),icd10_q45,3 +132516-0.0,"Source of report of Q50 (congenital malformations of ovaries, fallopian tubes and broad ligaments)",icd10_q50,3 +132518-0.0,Source of report of Q51 (congenital malformations of uterus and cervix),icd10_q51,3 +132520-0.0,Source of report of Q52 (other congenital malformations of female genitalia),icd10_q52,3 +132522-0.0,Source of report of Q53 (undescended testicle),icd10_q53,3 +132524-0.0,Source of report of Q54 (hypospadias),icd10_q54,3 +132526-0.0,Source of report of Q55 (other congenital malformations of male genital organs),icd10_q55,3 +132528-0.0,Source of report of Q56 (indeterminate sex and pseudohermaphroditism),icd10_q56,3 +132530-0.0,Source of report of Q60 (renal agenesis and other reduction defects of kidney),icd10_q60,3 +132532-0.0,Source of report of Q61 (cystic kidney disease),icd10_q61,3 +132534-0.0,Source of report of Q62 (congenital obstructive defects of renal pelvis and congenital malformations of ureter),icd10_q62,3 +132536-0.0,Source of report of Q63 (other congenital malformations of kidney),icd10_q63,3 +132538-0.0,Source of report of Q64 (other congenital malformations of urinary system),icd10_q64,3 +132540-0.0,Source of report of Q65 (congenital deformities of hip),icd10_q65,3 +132542-0.0,Source of report of Q66 (congenital deformities of feet),icd10_q66,3 +132544-0.0,"Source of report of Q67 (congenital musculoskeletal deformities of head, face, spine and chest)",icd10_q67,3 +132546-0.0,Source of report of Q68 (other congenital musculoskeletal deformities),icd10_q68,3 +132548-0.0,Source of report of Q69 (polydactyly),icd10_q69,3 +132550-0.0,Source of report of Q70 (syndactyly),icd10_q70,3 +132552-0.0,Source of report of Q71 (reduction defects of upper limb),icd10_q71,3 +132554-0.0,Source of report of Q72 (reduction defects of lower limb),icd10_q72,3 +132556-0.0,Source of report of Q73 (reduction defects of unspecified limb),icd10_q73,3 +132558-0.0,Source of report of Q74 (other congenital malformations of limb(s)),icd10_q74,3 +132560-0.0,Source of report of Q75 (other congenital malformations of skull and face bones),icd10_q75,3 +132562-0.0,Source of report of Q76 (congenital malformations of spine and bony thorax),icd10_q76,3 +132564-0.0,Source of report of Q77 (osteochondrodysplasia with defects of growth of tubular bones and spine),icd10_q77,3 +132566-0.0,Source of report of Q78 (other osteochondrodysplasias),icd10_q78,3 +132568-0.0,"Source of report of Q79 (congenital malformations of musculoskeletal system, not elsewhere classified)",icd10_q79,3 +132570-0.0,Source of report of Q80 (congenital ichthyosis),icd10_q80,3 +132572-0.0,Source of report of Q81 (epidermolysis bullosa),icd10_q81,3 +132574-0.0,Source of report of Q82 (other congenital malformations of skin),icd10_q82,3 +132576-0.0,Source of report of Q83 (congenital malformations of breast),icd10_q83,3 +132578-0.0,Source of report of Q84 (other congenital malformations of integument),icd10_q84,3 +132580-0.0,"Source of report of Q85 (phakomatoses, not elsewhere classified)",icd10_q85,3 +132582-0.0,"Source of report of Q86 (congenital malformation syndromes due to known exogenous causes, not elsewhere classified)",icd10_q86,3 +132584-0.0,Source of report of Q87 (other specified congenital malformation syndromes affecting multiple systems),icd10_q87,3 +132586-0.0,"Source of report of Q89 (other congenital malformations, not elsewhere classified)",icd10_q89,3 +132588-0.0,Source of report of Q90 (down's syndrome),icd10_q90,3 +132590-0.0,Source of report of Q91 (edwards' syndrome and patau's syndrome),icd10_q91,3 +132592-0.0,"Source of report of Q92 (other trisomies and partial trisomies of the autosomes, not elsewhere classified)",icd10_q92,3 +132594-0.0,"Source of report of Q93 (monosomies and deletions from the autosomes, not elsewhere classified)",icd10_q93,3 +132596-0.0,"Source of report of Q95 (balanced rearrangements and structural markers, not elsewhere classified)",icd10_q95,3 +132598-0.0,Source of report of Q96 (turner's syndrome),icd10_q96,3 +132600-0.0,"Source of report of Q97 (other sex chromosome abnormalities, female phenotype, not elsewhere classified)",icd10_q97,3 +132602-0.0,"Source of report of Q98 (other sex chromosome abnormalities, male phenotype, not elsewhere classified)",icd10_q98,3 +132604-0.0,"Source of report of Q99 (other chromosome abnormalities, not elsewhere classified)",icd10_q99,3 +40006-0.0,"Cancer code, ICD10 (array 0)",cancer_code_icd10_0,3 +40006-1.0,"Cancer code, ICD10 (array 1)",cancer_code_icd10_1,3 +40006-2.0,"Cancer code, ICD10 (array 2)",cancer_code_icd10_2,3 +40006-3.0,"Cancer code, ICD10 (array 3)",cancer_code_icd10_3,3 +40006-4.0,"Cancer code, ICD10 (array 4)",cancer_code_icd10_4,3 +40006-5.0,"Cancer code, ICD10 (array 5)",cancer_code_icd10_5,3 +40006-6.0,"Cancer code, ICD10 (array 6)",cancer_code_icd10_6,3 +40006-7.0,"Cancer code, ICD10 (array 7)",cancer_code_icd10_7,3 +40006-8.0,"Cancer code, ICD10 (array 8)",cancer_code_icd10_8,3 +40006-9.0,"Cancer code, ICD10 (array 9)",cancer_code_icd10_9,3 +40006-10.0,"Cancer code, ICD10 (array 10)",cancer_code_icd10_10,3 +40006-11.0,"Cancer code, ICD10 (array 11)",cancer_code_icd10_11,3 +40006-12.0,"Cancer code, ICD10 (array 12)",cancer_code_icd10_12,3 +40006-13.0,"Cancer code, ICD10 (array 13)",cancer_code_icd10_13,3 +40006-14.0,"Cancer code, ICD10 (array 14)",cancer_code_icd10_14,3 +40006-15.0,"Cancer code, ICD10 (array 15)",cancer_code_icd10_15,3 +40006-16.0,"Cancer code, ICD10 (array 16)",cancer_code_icd10_16,3 +130001-0.0,Date of first occurrence of A00 (cholera),icd10_a00_date,3 +130003-0.0,Date of first occurrence of A01 (typhoid and paratyphoid fevers),icd10_a01_date,3 +130005-0.0,Date of first occurrence of A02 (other salmonella infections),icd10_a02_date,3 +130007-0.0,Date of first occurrence of A03 (shigellosis),icd10_a03_date,3 +130009-0.0,Date of first occurrence of A04 (other bacterial intestinal infections),icd10_a04_date,3 +130011-0.0,Date of first occurrence of A05 (other bacterial foodborne intoxications),icd10_a05_date,3 +130013-0.0,Date of first occurrence of A06 (amoebiasis),icd10_a06_date,3 +130015-0.0,Date of first occurrence of A07 (other protozoal intestinal diseases),icd10_a07_date,3 +130017-0.0,Date of first occurrence of A08 (viral and other specified intestinal infections),icd10_a08_date,3 +130019-0.0,Date of first occurrence of A09 (diarrhoea and gastro-enteritis of presumed infectious origin),icd10_a09_date,3 +130021-0.0,"Date of first occurrence of A15 (respiratory tuberculosis, bacteriologically and histologically confirmed)",icd10_a15_date,3 +130023-0.0,"Date of first occurrence of A16 (respiratory tuberculosis, not confirmed bacteriologically or histologically)",icd10_a16_date,3 +130025-0.0,Date of first occurrence of A17 (tuberculosis of nervous system),icd10_a17_date,3 +130027-0.0,Date of first occurrence of A18 (tuberculosis of other organs),icd10_a18_date,3 +130029-0.0,Date of first occurrence of A19 (miliary tuberculosis),icd10_a19_date,3 +130031-0.0,Date of first occurrence of A20 (plague),icd10_a20_date,3 +130035-0.0,Date of first occurrence of A22 (anthrax),icd10_a22_date,3 +130037-0.0,Date of first occurrence of A23 (brucellosis),icd10_a23_date,3 +130039-0.0,Date of first occurrence of A24 (glanders and melioidosis),icd10_a24_date,3 +130041-0.0,Date of first occurrence of A25 (rat-bite fevers),icd10_a25_date,3 +130043-0.0,Date of first occurrence of A26 (erysipeloid),icd10_a26_date,3 +130045-0.0,Date of first occurrence of A27 (leptospirosis),icd10_a27_date,3 +130047-0.0,"Date of first occurrence of A28 (other zoonotic bacterial diseases, not elsewhere classified)",icd10_a28_date,3 +130049-0.0,Date of first occurrence of A30 (leprosy [hansen's disease]),icd10_a30_date,3 +130051-0.0,Date of first occurrence of A31 (infection due to other mycobacteria),icd10_a31_date,3 +130053-0.0,Date of first occurrence of A32 (listeriosis),icd10_a32_date,3 +130055-0.0,Date of first occurrence of A33 (tetanus neonatorum),icd10_a33_date,3 +130059-0.0,Date of first occurrence of A35 (other tetanus),icd10_a35_date,3 +130061-0.0,Date of first occurrence of A36 (diphtheria),icd10_a36_date,3 +130063-0.0,Date of first occurrence of A37 (whooping cough),icd10_a37_date,3 +130065-0.0,Date of first occurrence of A38 (scarlet fever),icd10_a38_date,3 +130067-0.0,Date of first occurrence of A39 (meningococcal infection),icd10_a39_date,3 +130069-0.0,Date of first occurrence of A40 (streptococcal septicaemia),icd10_a40_date,3 +130071-0.0,Date of first occurrence of A41 (other septicaemia),icd10_a41_date,3 +130073-0.0,Date of first occurrence of A42 (actinomycosis),icd10_a42_date,3 +130075-0.0,Date of first occurrence of A43 (nocardiosis),icd10_a43_date,3 +130077-0.0,Date of first occurrence of A44 (bartonellosis),icd10_a44_date,3 +130079-0.0,Date of first occurrence of A46 (erysipelas),icd10_a46_date,3 +130081-0.0,"Date of first occurrence of A48 (other bacterial diseases, not elsewhere classified)",icd10_a48_date,3 +130083-0.0,Date of first occurrence of A49 (bacterial infection of unspecified site),icd10_a49_date,3 +130085-0.0,Date of first occurrence of A50 (congenital syphilis),icd10_a50_date,3 +130087-0.0,Date of first occurrence of A51 (early syphilis),icd10_a51_date,3 +130089-0.0,Date of first occurrence of A52 (late syphilis),icd10_a52_date,3 +130091-0.0,Date of first occurrence of A53 (other and unspecified syphilis),icd10_a53_date,3 +130093-0.0,Date of first occurrence of A54 (gonococcal infection),icd10_a54_date,3 +130095-0.0,Date of first occurrence of A55 (chlamydial lymphogranuloma (venereum)),icd10_a55_date,3 +130097-0.0,Date of first occurrence of A56 (other sexually transmitted chlamydial diseases),icd10_a56_date,3 +130101-0.0,Date of first occurrence of A58 (granuloma inguinale),icd10_a58_date,3 +130103-0.0,Date of first occurrence of A59 (trichomoniasis),icd10_a59_date,3 +130105-0.0,Date of first occurrence of A60 (anogenital herpesviral [herpes simplex] infections),icd10_a60_date,3 +130107-0.0,"Date of first occurrence of A63 (other predominantly sexually transmitted diseases, not elsewhere classified)",icd10_a63_date,3 +130109-0.0,Date of first occurrence of A64 (unspecified sexually transmitted disease),icd10_a64_date,3 +130113-0.0,Date of first occurrence of A66 (yaws),icd10_a66_date,3 +130115-0.0,Date of first occurrence of A67 (pinta [carate]),icd10_a67_date,3 +130117-0.0,Date of first occurrence of A68 (relapsing fevers),icd10_a68_date,3 +130119-0.0,Date of first occurrence of A69 (other spirochaetal infections),icd10_a69_date,3 +130121-0.0,Date of first occurrence of A70 (chlamydia psittaci infection),icd10_a70_date,3 +130123-0.0,Date of first occurrence of A71 (trachoma),icd10_a71_date,3 +130125-0.0,Date of first occurrence of A74 (other diseases caused by chlamydiae),icd10_a74_date,3 +130127-0.0,Date of first occurrence of A75 (typhus fever),icd10_a75_date,3 +130129-0.0,Date of first occurrence of A77 (spotted fever [tick-borne rickettsioses]),icd10_a77_date,3 +130131-0.0,Date of first occurrence of A78 (q fever),icd10_a78_date,3 +130133-0.0,Date of first occurrence of A79 (other rickettsioses),icd10_a79_date,3 +130135-0.0,Date of first occurrence of A80 (acute poliomyelitis),icd10_a80_date,3 +130137-0.0,Date of first occurrence of A81 (atypical virus infections of central nervous system),icd10_a81_date,3 +130139-0.0,Date of first occurrence of A82 (rabies),icd10_a82_date,3 +130141-0.0,Date of first occurrence of A83 (mosquito-borne viral encephalitis),icd10_a83_date,3 +130143-0.0,Date of first occurrence of A84 (tick-borne viral encephalitis),icd10_a84_date,3 +130145-0.0,"Date of first occurrence of A85 (other viral encephalitis, not elsewhere classified)",icd10_a85_date,3 +130147-0.0,Date of first occurrence of A86 (unspecified viral encephalitis),icd10_a86_date,3 +130149-0.0,Date of first occurrence of A87 (viral meningitis),icd10_a87_date,3 +130151-0.0,"Date of first occurrence of A88 (other viral infections of central nervous system, not elsewhere classified)",icd10_a88_date,3 +130153-0.0,Date of first occurrence of A89 (unspecified viral infection of central nervous system),icd10_a89_date,3 +130155-0.0,Date of first occurrence of A90 (dengue fever [classical dengue]),icd10_a90_date,3 +130157-0.0,Date of first occurrence of A91 (dengue haemorrhagic fever),icd10_a91_date,3 +130159-0.0,Date of first occurrence of A92 (other mosquito-borne viral fevers),icd10_a92_date,3 +130161-0.0,"Date of first occurrence of A93 (other arthropod-borne viral fevers, not elsewhere classified)",icd10_a93_date,3 +130163-0.0,Date of first occurrence of A94 (unspecified arthropod-borne viral fever),icd10_a94_date,3 +130165-0.0,Date of first occurrence of A95 (yellow fever),icd10_a95_date,3 +130169-0.0,Date of first occurrence of A97 (dengue),icd10_a97_date,3 +130171-0.0,"Date of first occurrence of A98 (other viral haemorrhagic fevers, not elsewhere classified)",icd10_a98_date,3 +130175-0.0,Date of first occurrence of B00 (herpesviral [herpes simplex] infections),icd10_b00_date,3 +130177-0.0,Date of first occurrence of B01 (varicella [chickenpox]),icd10_b01_date,3 +130179-0.0,Date of first occurrence of B02 (zoster [herpes zoster]),icd10_b02_date,3 +130181-0.0,Date of first occurrence of B03 (smallpox),icd10_b03_date,3 +130185-0.0,Date of first occurrence of B05 (measles),icd10_b05_date,3 +130187-0.0,Date of first occurrence of B06 (rubella [german measles]),icd10_b06_date,3 +130189-0.0,Date of first occurrence of B07 (viral warts),icd10_b07_date,3 +130191-0.0,"Date of first occurrence of B08 (other viral infections characterised by skin and mucous membrane lesions, not elsewhere classified)",icd10_b08_date,3 +130193-0.0,Date of first occurrence of B09 (unspecified viral infection characterised by skin and mucous membrane lesions),icd10_b09_date,3 +130195-0.0,Date of first occurrence of B15 (acute hepatitis a),icd10_b15_date,3 +130197-0.0,Date of first occurrence of B16 (acute hepatitis b),icd10_b16_date,3 +130199-0.0,Date of first occurrence of B17 (other acute viral hepatitis),icd10_b17_date,3 +130201-0.0,Date of first occurrence of B18 (chronic viral hepatitis),icd10_b18_date,3 +130203-0.0,Date of first occurrence of B19 (unspecified viral hepatitis),icd10_b19_date,3 +130205-0.0,Date of first occurrence of B20 (human immunodeficiency virus [hiv] disease resulting in infectious and parasitic diseases),icd10_b20_date,3 +130207-0.0,Date of first occurrence of B21 (human immunodeficiency virus [hiv] disease resulting in malignant neoplasms),icd10_b21_date,3 +130209-0.0,Date of first occurrence of B22 (human immunodeficiency virus [hiv] disease resulting in other specified diseases),icd10_b22_date,3 +130211-0.0,Date of first occurrence of B23 (human immunodeficiency virus [hiv] disease resulting in other conditions),icd10_b23_date,3 +130213-0.0,Date of first occurrence of B24 (unspecified human immunodeficiency virus [hiv] disease),icd10_b24_date,3 +130215-0.0,Date of first occurrence of B25 (cytomegaloviral disease),icd10_b25_date,3 +130217-0.0,Date of first occurrence of B26 (mumps),icd10_b26_date,3 +130219-0.0,Date of first occurrence of B27 (infectious mononucleosis),icd10_b27_date,3 +130221-0.0,Date of first occurrence of B30 (viral conjunctivitis),icd10_b30_date,3 +130223-0.0,"Date of first occurrence of B33 (other viral diseases, not elsewhere classified)",icd10_b33_date,3 +130225-0.0,Date of first occurrence of B34 (viral infection of unspecified site),icd10_b34_date,3 +130227-0.0,Date of first occurrence of B35 (dermatophytosis),icd10_b35_date,3 +130229-0.0,Date of first occurrence of B36 (other superficial mycoses),icd10_b36_date,3 +130231-0.0,Date of first occurrence of B37 (candidiasis),icd10_b37_date,3 +130233-0.0,Date of first occurrence of B38 (coccidioidomycosis),icd10_b38_date,3 +130235-0.0,Date of first occurrence of B39 (histoplasmosis),icd10_b39_date,3 +130237-0.0,Date of first occurrence of B40 (blastomycosis),icd10_b40_date,3 +130241-0.0,Date of first occurrence of B42 (sporotrichosis),icd10_b42_date,3 +130243-0.0,Date of first occurrence of B43 (chromomycosis and phaeomycotic abscess),icd10_b43_date,3 +130245-0.0,Date of first occurrence of B44 (aspergillosis),icd10_b44_date,3 +130247-0.0,Date of first occurrence of B45 (cryptococcosis),icd10_b45_date,3 +130249-0.0,Date of first occurrence of B46 (zygomycosis),icd10_b46_date,3 +130251-0.0,Date of first occurrence of B47 (mycetoma),icd10_b47_date,3 +130253-0.0,"Date of first occurrence of B48 (other mycoses, not elsewhere classified)",icd10_b48_date,3 +130255-0.0,Date of first occurrence of B49 (unspecified mycosis),icd10_b49_date,3 +130257-0.0,Date of first occurrence of B50 (plasmodium falciparum malaria),icd10_b50_date,3 +130259-0.0,Date of first occurrence of B51 (plasmodium vivax malaria),icd10_b51_date,3 +130261-0.0,Date of first occurrence of B52 (plasmodium malariae malaria),icd10_b52_date,3 +130263-0.0,Date of first occurrence of B53 (other parasitologically confirmed malaria),icd10_b53_date,3 +130265-0.0,Date of first occurrence of B54 (unspecified malaria),icd10_b54_date,3 +130267-0.0,Date of first occurrence of B55 (leishmaniasis),icd10_b55_date,3 +130271-0.0,Date of first occurrence of B57 (chagas' disease),icd10_b57_date,3 +130273-0.0,Date of first occurrence of B58 (toxoplasmosis),icd10_b58_date,3 +130275-0.0,Date of first occurrence of B59 (pneumocystosis),icd10_b59_date,3 +130277-0.0,"Date of first occurrence of B60 (other protozoal diseases, not elsewhere classified)",icd10_b60_date,3 +130281-0.0,Date of first occurrence of B65 (schistosomiasis [bilharziasis]),icd10_b65_date,3 +130283-0.0,Date of first occurrence of B66 (other fluke infections),icd10_b66_date,3 +130285-0.0,Date of first occurrence of B67 (echinococcosis),icd10_b67_date,3 +130287-0.0,Date of first occurrence of B68 (taeniasis),icd10_b68_date,3 +130289-0.0,Date of first occurrence of B69 (cysticercosis),icd10_b69_date,3 +130293-0.0,Date of first occurrence of B71 (other cestode infections),icd10_b71_date,3 +130297-0.0,Date of first occurrence of B73 (onchocerciasis),icd10_b73_date,3 +130299-0.0,Date of first occurrence of B74 (filariasis),icd10_b74_date,3 +130301-0.0,Date of first occurrence of B75 (trichinellosis),icd10_b75_date,3 +130303-0.0,Date of first occurrence of B76 (hookworm diseases),icd10_b76_date,3 +130305-0.0,Date of first occurrence of B77 (ascariasis),icd10_b77_date,3 +130307-0.0,Date of first occurrence of B78 (strongyloidiasis),icd10_b78_date,3 +130309-0.0,Date of first occurrence of B79 (trichuriasis),icd10_b79_date,3 +130311-0.0,Date of first occurrence of B80 (enterobiasis),icd10_b80_date,3 +130313-0.0,"Date of first occurrence of B81 (other intestinal helminthiases, not elsewhere classified)",icd10_b81_date,3 +130315-0.0,Date of first occurrence of B82 (unspecified intestinal parasitism),icd10_b82_date,3 +130317-0.0,Date of first occurrence of B83 (other helminthiases),icd10_b83_date,3 +130319-0.0,Date of first occurrence of B85 (pediculosis and phthiriasis),icd10_b85_date,3 +130321-0.0,Date of first occurrence of B86 (scabies),icd10_b86_date,3 +130323-0.0,Date of first occurrence of B87 (myiasis),icd10_b87_date,3 +130325-0.0,Date of first occurrence of B88 (other infestations),icd10_b88_date,3 +130327-0.0,Date of first occurrence of B89 (unspecified parasitic disease),icd10_b89_date,3 +130329-0.0,Date of first occurrence of B90 (sequelae of tuberculosis),icd10_b90_date,3 +130331-0.0,Date of first occurrence of B91 (sequelae of poliomyelitis),icd10_b91_date,3 +130335-0.0,Date of first occurrence of B94 (sequelae of other and unspecified infectious and parasitic diseases),icd10_b94_date,3 +130337-0.0,Date of first occurrence of B95 (streptococcus and staphylococcus as the cause of diseases classified to other chapters),icd10_b95_date,3 +130339-0.0,Date of first occurrence of B96 (other bacterial agents as the cause of diseases classified to other chapters),icd10_b96_date,3 +130341-0.0,Date of first occurrence of B97 (viral agents as the cause of diseases classified to other chapters),icd10_b97_date,3 +130343-0.0,Date of first occurrence of B98 (other specified infectious agents as the cause of diseases classified to other chapters),icd10_b98_date,3 +130345-0.0,Date of first occurrence of B99 (other and unspecified infectious diseases),icd10_b99_date,3 +130623-0.0,Date of first occurrence of D50 (iron deficiency anaemia),icd10_d50_date,3 +130625-0.0,Date of first occurrence of D51 (vitamin b12 deficiency anaemia),icd10_d51_date,3 +130627-0.0,Date of first occurrence of D52 (folate deficiency anaemia),icd10_d52_date,3 +130629-0.0,Date of first occurrence of D53 (other nutritional anaemias),icd10_d53_date,3 +130631-0.0,Date of first occurrence of D55 (anaemia due to enzyme disorders),icd10_d55_date,3 +130633-0.0,Date of first occurrence of D56 (thalassaemia),icd10_d56_date,3 +130635-0.0,Date of first occurrence of D57 (sickle-cell disorders),icd10_d57_date,3 +130637-0.0,Date of first occurrence of D58 (other hereditary haemolytic anaemias),icd10_d58_date,3 +130639-0.0,Date of first occurrence of D59 (acquired haemolytic anaemia),icd10_d59_date,3 +130641-0.0,Date of first occurrence of D60 (acquired pure red cell aplasia [erythroblastopenia]),icd10_d60_date,3 +130643-0.0,Date of first occurrence of D61 (other aplastic anaemias),icd10_d61_date,3 +130645-0.0,Date of first occurrence of D62 (acute posthaemorrhagic anaemia),icd10_d62_date,3 +130647-0.0,Date of first occurrence of D63 (anaemia in chronic diseases classified elsewhere),icd10_d63_date,3 +130649-0.0,Date of first occurrence of D64 (other anaemias),icd10_d64_date,3 +130651-0.0,Date of first occurrence of D65 (disseminated intravascular coagulation [defibrination syndrome]),icd10_d65_date,3 +130653-0.0,Date of first occurrence of D66 (hereditary factor viii deficiency),icd10_d66_date,3 +130655-0.0,Date of first occurrence of D67 (hereditary factor ix deficiency),icd10_d67_date,3 +130657-0.0,Date of first occurrence of D68 (other coagulation defects),icd10_d68_date,3 +130659-0.0,Date of first occurrence of D69 (purpura and other haemorrhagic conditions),icd10_d69_date,3 +130661-0.0,Date of first occurrence of D70 (agranulocytosis),icd10_d70_date,3 +130663-0.0,Date of first occurrence of D71 (functional disorders of polymorphonuclear neutrophils),icd10_d71_date,3 +130665-0.0,Date of first occurrence of D72 (other disorders of white blood cells),icd10_d72_date,3 +130667-0.0,Date of first occurrence of D73 (diseases of spleen),icd10_d73_date,3 +130669-0.0,Date of first occurrence of D74 (methaemoglobinaemia),icd10_d74_date,3 +130671-0.0,Date of first occurrence of D75 (other diseases of blood and blood-forming organs),icd10_d75_date,3 +130673-0.0,Date of first occurrence of D76 (certain diseases involving lymphoreticular tissue and reticulohistiocytic system),icd10_d76_date,3 +130675-0.0,Date of first occurrence of D77 (other disorders of blood and blood-forming organs in diseases classified elsewhere),icd10_d77_date,3 +130677-0.0,Date of first occurrence of D80 (immunodeficiency with predominantly antibody defects),icd10_d80_date,3 +130679-0.0,Date of first occurrence of D81 (combined immunodeficiencies),icd10_d81_date,3 +130681-0.0,Date of first occurrence of D82 (immunodeficiency associated with other major defects),icd10_d82_date,3 +130683-0.0,Date of first occurrence of D83 (common variable immunodeficiency),icd10_d83_date,3 +130685-0.0,Date of first occurrence of D84 (other immunodeficiencies),icd10_d84_date,3 +130687-0.0,Date of first occurrence of D86 (sarcoidosis),icd10_d86_date,3 +130689-0.0,"Date of first occurrence of D89 (other disorders involving the immune mechanism, not elsewhere classified)",icd10_d89_date,3 +130693-0.0,Date of first occurrence of E01 (iodine-deficiency-related thyroid disorders and allied conditions),icd10_e01_date,3 +130695-0.0,Date of first occurrence of E02 (subclinical iodine-deficiency hypothyroidism),icd10_e02_date,3 +130697-0.0,Date of first occurrence of E03 (other hypothyroidism),icd10_e03_date,3 +130699-0.0,Date of first occurrence of E04 (other non-toxic goitre),icd10_e04_date,3 +130701-0.0,Date of first occurrence of E05 (thyrotoxicosis [hyperthyroidism]),icd10_e05_date,3 +130703-0.0,Date of first occurrence of E06 (thyroiditis),icd10_e06_date,3 +130705-0.0,Date of first occurrence of E07 (other disorders of thyroid),icd10_e07_date,3 +130707-0.0,Date of first occurrence of E10 (insulin-dependent diabetes mellitus),icd10_e10_date,3 +130709-0.0,Date of first occurrence of E11 (non-insulin-dependent diabetes mellitus),icd10_e11_date,3 +130711-0.0,Date of first occurrence of E12 (malnutrition-related diabetes mellitus),icd10_e12_date,3 +130713-0.0,Date of first occurrence of E13 (other specified diabetes mellitus),icd10_e13_date,3 +130715-0.0,Date of first occurrence of E14 (unspecified diabetes mellitus),icd10_e14_date,3 +130717-0.0,Date of first occurrence of E15 (nondiabetic hypoglycaemic coma),icd10_e15_date,3 +130719-0.0,Date of first occurrence of E16 (other disorders of pancreatic internal secretion),icd10_e16_date,3 +130721-0.0,Date of first occurrence of E20 (hypoparathyroidism),icd10_e20_date,3 +130723-0.0,Date of first occurrence of E21 (hyperparathyroidism and other disorders of parathyroid gland),icd10_e21_date,3 +130725-0.0,Date of first occurrence of E22 (hyperfunction of pituitary gland),icd10_e22_date,3 +130727-0.0,Date of first occurrence of E23 (hypofunction and other disorders of pituitary gland),icd10_e23_date,3 +130729-0.0,Date of first occurrence of E24 (cushing's syndrome),icd10_e24_date,3 +130731-0.0,Date of first occurrence of E25 (adrenogenital disorders),icd10_e25_date,3 +130733-0.0,Date of first occurrence of E26 (hyperaldosteronism),icd10_e26_date,3 +130735-0.0,Date of first occurrence of E27 (other disorders of adrenal gland),icd10_e27_date,3 +130737-0.0,Date of first occurrence of E28 (ovarian dysfunction),icd10_e28_date,3 +130739-0.0,Date of first occurrence of E29 (testicular dysfunction),icd10_e29_date,3 +130741-0.0,"Date of first occurrence of E30 (disorders of puberty, not elsewhere classified)",icd10_e30_date,3 +130743-0.0,Date of first occurrence of E31 (polyglandular dysfunction),icd10_e31_date,3 +130745-0.0,Date of first occurrence of E32 (diseases of thymus),icd10_e32_date,3 +130747-0.0,Date of first occurrence of E34 (other endocrine disorders),icd10_e34_date,3 +130749-0.0,Date of first occurrence of E35 (disorders of endocrine glands in diseases classified elsewhere),icd10_e35_date,3 +130753-0.0,Date of first occurrence of E41 (nutritional marasmus),icd10_e41_date,3 +130757-0.0,Date of first occurrence of E43 (unspecified severe protein-energy malnutrition),icd10_e43_date,3 +130759-0.0,Date of first occurrence of E44 (protein-energy malnutrition of moderate and mild degree),icd10_e44_date,3 +130761-0.0,Date of first occurrence of E45 (retarded development following protein-energy malnutrition),icd10_e45_date,3 +130763-0.0,Date of first occurrence of E46 (unspecified protein-energy malnutrition),icd10_e46_date,3 +130765-0.0,Date of first occurrence of E50 (vitamin a deficiency),icd10_e50_date,3 +130767-0.0,Date of first occurrence of E51 (thiamine deficiency),icd10_e51_date,3 +130769-0.0,Date of first occurrence of E52 (niacin deficiency [pellagra]),icd10_e52_date,3 +130771-0.0,Date of first occurrence of E53 (deficiency of other b group vitamins),icd10_e53_date,3 +130773-0.0,Date of first occurrence of E54 (ascorbic acid deficiency),icd10_e54_date,3 +130775-0.0,Date of first occurrence of E55 (vitamin d deficiency),icd10_e55_date,3 +130777-0.0,Date of first occurrence of E56 (other vitamin deficiencies),icd10_e56_date,3 +130779-0.0,Date of first occurrence of E58 (dietary calcium deficiency),icd10_e58_date,3 +130781-0.0,Date of first occurrence of E59 (dietary selenium deficiency),icd10_e59_date,3 +130783-0.0,Date of first occurrence of E60 (dietary zinc deficiency),icd10_e60_date,3 +130785-0.0,Date of first occurrence of E61 (deficiency of other nutrient elements),icd10_e61_date,3 +130787-0.0,Date of first occurrence of E63 (other nutritional deficiencies),icd10_e63_date,3 +130789-0.0,Date of first occurrence of E64 (sequelae of malnutrition and other nutritional deficiencies),icd10_e64_date,3 +130791-0.0,Date of first occurrence of E65 (localised adiposity),icd10_e65_date,3 +130793-0.0,Date of first occurrence of E66 (obesity),icd10_e66_date,3 +130795-0.0,Date of first occurrence of E67 (other hyperalimentation),icd10_e67_date,3 +130797-0.0,Date of first occurrence of E68 (sequelae of hyperalimentation),icd10_e68_date,3 +130799-0.0,Date of first occurrence of E70 (disorders of aromatic amino-acid metabolism),icd10_e70_date,3 +130801-0.0,Date of first occurrence of E71 (disorders of branched-chain amino-acid metabolism and fatty-acid metabolism),icd10_e71_date,3 +130803-0.0,Date of first occurrence of E72 (other disorders of amino-acid metabolism),icd10_e72_date,3 +130805-0.0,Date of first occurrence of E73 (lactose intolerance),icd10_e73_date,3 +130807-0.0,Date of first occurrence of E74 (other disorders of carbohydrate metabolism),icd10_e74_date,3 +130809-0.0,Date of first occurrence of E75 (disorders of sphingolipid metabolism and other lipid storage disorders),icd10_e75_date,3 +130811-0.0,Date of first occurrence of E76 (disorders of glycosaminoglycan metabolism),icd10_e76_date,3 +130813-0.0,Date of first occurrence of E77 (disorders of glycoprotein metabolism),icd10_e77_date,3 +130815-0.0,Date of first occurrence of E78 (disorders of lipoprotein metabolism and other lipidaemias),icd10_e78_date,3 +130817-0.0,Date of first occurrence of E79 (disorders of purine and pyrimidine metabolism),icd10_e79_date,3 +130819-0.0,Date of first occurrence of E80 (disorders of porphyrin and bilirubin metabolism),icd10_e80_date,3 +130821-0.0,Date of first occurrence of E83 (disorders of mineral metabolism),icd10_e83_date,3 +130823-0.0,Date of first occurrence of E84 (cystic fibrosis),icd10_e84_date,3 +130825-0.0,Date of first occurrence of E85 (amyloidosis),icd10_e85_date,3 +130827-0.0,Date of first occurrence of E86 (volume depletion),icd10_e86_date,3 +130829-0.0,"Date of first occurrence of E87 (other disorders of fluid, electrolyte and acid-base balance)",icd10_e87_date,3 +130831-0.0,Date of first occurrence of E88 (other metabolic disorders),icd10_e88_date,3 +130833-0.0,"Date of first occurrence of E89 (postprocedural endocrine and metabolic disorders, not elsewhere classified)",icd10_e89_date,3 +130837-0.0,Date of first occurrence of F00 (dementia in alzheimer's disease),icd10_f00_date,3 +130839-0.0,Date of first occurrence of F01 (vascular dementia),icd10_f01_date,3 +130841-0.0,Date of first occurrence of F02 (dementia in other diseases classified elsewhere),icd10_f02_date,3 +130843-0.0,Date of first occurrence of F03 (unspecified dementia),icd10_f03_date,3 +130845-0.0,"Date of first occurrence of F04 (organic amnesic syndrome, not induced by alcohol and other psychoactive substances)",icd10_f04_date,3 +130847-0.0,"Date of first occurrence of F05 (delirium, not induced by alcohol and other psychoactive substances)",icd10_f05_date,3 +130849-0.0,Date of first occurrence of F06 (other mental disorders due to brain damage and dysfunction and to physical disease),icd10_f06_date,3 +130851-0.0,"Date of first occurrence of F07 (personality and behavioural disorders due to brain disease, damage and dysfunction)",icd10_f07_date,3 +130853-0.0,Date of first occurrence of F09 (unspecified organic or symptomatic mental disorder),icd10_f09_date,3 +130855-0.0,Date of first occurrence of F10 (mental and behavioural disorders due to use of alcohol),icd10_f10_date,3 +130857-0.0,Date of first occurrence of F11 (mental and behavioural disorders due to use of opioids),icd10_f11_date,3 +130859-0.0,Date of first occurrence of F12 (mental and behavioural disorders due to use of cannabinoids),icd10_f12_date,3 +130861-0.0,Date of first occurrence of F13 (mental and behavioural disorders due to use of sedatives or hypnotics),icd10_f13_date,3 +130863-0.0,Date of first occurrence of F14 (mental and behavioural disorders due to use of cocaine),icd10_f14_date,3 +130865-0.0,"Date of first occurrence of F15 (mental and behavioural disorders due to use of other stimulants, including caffeine)",icd10_f15_date,3 +130867-0.0,Date of first occurrence of F16 (mental and behavioural disorders due to use of hallucinogens),icd10_f16_date,3 +130869-0.0,Date of first occurrence of F17 (mental and behavioural disorders due to use of tobacco),icd10_f17_date,3 +130871-0.0,Date of first occurrence of F18 (mental and behavioural disorders due to use of volatile solvents),icd10_f18_date,3 +130873-0.0,Date of first occurrence of F19 (mental and behavioural disorders due to multiple drug use and use of other psychoactive substances),icd10_f19_date,3 +130875-0.0,Date of first occurrence of F20 (schizophrenia),icd10_f20_date,3 +130877-0.0,Date of first occurrence of F21 (schizotypal disorder),icd10_f21_date,3 +130879-0.0,Date of first occurrence of F22 (persistent delusional disorders),icd10_f22_date,3 +130881-0.0,Date of first occurrence of F23 (acute and transient psychotic disorders),icd10_f23_date,3 +130883-0.0,Date of first occurrence of F24 (induced delusional disorder),icd10_f24_date,3 +130885-0.0,Date of first occurrence of F25 (schizoaffective disorders),icd10_f25_date,3 +130887-0.0,Date of first occurrence of F28 (other nonorganic psychotic disorders),icd10_f28_date,3 +130889-0.0,Date of first occurrence of F29 (unspecified nonorganic psychosis),icd10_f29_date,3 +130891-0.0,Date of first occurrence of F30 (manic episode),icd10_f30_date,3 +130893-0.0,Date of first occurrence of F31 (bipolar affective disorder),icd10_f31_date,3 +130895-0.0,Date of first occurrence of F32 (depressive episode),icd10_f32_date,3 +130897-0.0,Date of first occurrence of F33 (recurrent depressive disorder),icd10_f33_date,3 +130899-0.0,Date of first occurrence of F34 (persistent mood [affective] disorders),icd10_f34_date,3 +130901-0.0,Date of first occurrence of F38 (other mood [affective] disorders),icd10_f38_date,3 +130903-0.0,Date of first occurrence of F39 (unspecified mood [affective] disorder),icd10_f39_date,3 +130905-0.0,Date of first occurrence of F40 (phobic anxiety disorders),icd10_f40_date,3 +130907-0.0,Date of first occurrence of F41 (other anxiety disorders),icd10_f41_date,3 +130909-0.0,Date of first occurrence of F42 (obsessive-compulsive disorder),icd10_f42_date,3 +130911-0.0,"Date of first occurrence of F43 (reaction to severe stress, and adjustment disorders)",icd10_f43_date,3 +130913-0.0,Date of first occurrence of F44 (dissociative [conversion] disorders),icd10_f44_date,3 +130915-0.0,Date of first occurrence of F45 (somatoform disorders),icd10_f45_date,3 +130917-0.0,Date of first occurrence of F48 (other neurotic disorders),icd10_f48_date,3 +130919-0.0,Date of first occurrence of F50 (eating disorders),icd10_f50_date,3 +130921-0.0,Date of first occurrence of F51 (nonorganic sleep disorders),icd10_f51_date,3 +130923-0.0,"Date of first occurrence of F52 (sexual dysfunction, not caused by organic disorder or disease)",icd10_f52_date,3 +130925-0.0,"Date of first occurrence of F53 (mental and behavioural disorders associated with the puerperium, not elsewhere classified)",icd10_f53_date,3 +130927-0.0,Date of first occurrence of F54 (psychological and behavioural factors associated with disorders or diseases classified elsewhere),icd10_f54_date,3 +130929-0.0,Date of first occurrence of F55 (abuse of non-dependence-producing substances),icd10_f55_date,3 +130931-0.0,Date of first occurrence of F59 (unspecified behavioural syndromes associated with physiological disturbances and physical factors),icd10_f59_date,3 +130933-0.0,Date of first occurrence of F60 (specific personality disorders),icd10_f60_date,3 +130935-0.0,Date of first occurrence of F61 (mixed and other personality disorders),icd10_f61_date,3 +130937-0.0,"Date of first occurrence of F62 (enduring personality changes, not attributable to brain damage and disease)",icd10_f62_date,3 +130939-0.0,Date of first occurrence of F63 (habit and impulse disorders),icd10_f63_date,3 +130941-0.0,Date of first occurrence of F64 (gender identity disorders),icd10_f64_date,3 +130943-0.0,Date of first occurrence of F65 (disorders of sexual preference),icd10_f65_date,3 +130945-0.0,Date of first occurrence of F66 (psychological and behavioural disorders associated with sexual development and orientation),icd10_f66_date,3 +130947-0.0,Date of first occurrence of F68 (other disorders of adult personality and behaviour),icd10_f68_date,3 +130949-0.0,Date of first occurrence of F69 (unspecified disorder of adult personality and behaviour),icd10_f69_date,3 +130951-0.0,Date of first occurrence of F70 (mild mental retardation),icd10_f70_date,3 +130953-0.0,Date of first occurrence of F71 (moderate mental retardation),icd10_f71_date,3 +130955-0.0,Date of first occurrence of F72 (severe mental retardation),icd10_f72_date,3 +130959-0.0,Date of first occurrence of F78 (other mental retardation),icd10_f78_date,3 +130961-0.0,Date of first occurrence of F79 (unspecified mental retardation),icd10_f79_date,3 +130963-0.0,Date of first occurrence of F80 (specific developmental disorders of speech and language),icd10_f80_date,3 +130965-0.0,Date of first occurrence of F81 (specific developmental disorders of scholastic skills),icd10_f81_date,3 +130967-0.0,Date of first occurrence of F82 (specific developmental disorder of motor function),icd10_f82_date,3 +130969-0.0,Date of first occurrence of F83 (mixed specific developmental disorders),icd10_f83_date,3 +130971-0.0,Date of first occurrence of F84 (pervasive developmental disorders),icd10_f84_date,3 +130973-0.0,Date of first occurrence of F88 (other disorders of psychological development),icd10_f88_date,3 +130975-0.0,Date of first occurrence of F89 (unspecified disorder of psychological development),icd10_f89_date,3 +130977-0.0,Date of first occurrence of F90 (hyperkinetic disorders),icd10_f90_date,3 +130979-0.0,Date of first occurrence of F91 (conduct disorders),icd10_f91_date,3 +130981-0.0,Date of first occurrence of F92 (mixed disorders of conduct and emotions),icd10_f92_date,3 +130983-0.0,Date of first occurrence of F93 (emotional disorders with onset specific to childhood),icd10_f93_date,3 +130985-0.0,Date of first occurrence of F94 (disorders of social functioning with onset specific to childhood and adolescence),icd10_f94_date,3 +130987-0.0,Date of first occurrence of F95 (tic disorders),icd10_f95_date,3 +130989-0.0,Date of first occurrence of F98 (other behavioural and emotional disorders with onset usually occurring in childhood and adolescence),icd10_f98_date,3 +130991-0.0,"Date of first occurrence of F99 (mental disorder, not otherwise specified)",icd10_f99_date,3 +130993-0.0,"Date of first occurrence of G00 (bacterial meningitis, not elsewhere classified)",icd10_g00_date,3 +130995-0.0,Date of first occurrence of G01 (meningitis in bacterial diseases classified elsewhere),icd10_g01_date,3 +130997-0.0,Date of first occurrence of G02 (meningitis in other infectious and parasitic diseases classified elsewhere),icd10_g02_date,3 +130999-0.0,Date of first occurrence of G03 (meningitis due to other and unspecified causes),icd10_g03_date,3 +131001-0.0,"Date of first occurrence of G04 (encephalitis, myelitis and encephalomyelitis)",icd10_g04_date,3 +131003-0.0,"Date of first occurrence of G05 (encephalitis, myelitis and encephalomyelitis in diseases classified elsewhere)",icd10_g05_date,3 +131005-0.0,Date of first occurrence of G06 (intracranial and intraspinal abscess and granuloma),icd10_g06_date,3 +131007-0.0,Date of first occurrence of G07 (intracranial and intraspinal abscess and granuloma in diseases classified elsewhere),icd10_g07_date,3 +131009-0.0,Date of first occurrence of G08 (intracranial and intraspinal phlebitis and thrombophlebitis),icd10_g08_date,3 +131011-0.0,Date of first occurrence of G09 (sequelae of inflammatory diseases of central nervous system),icd10_g09_date,3 +131013-0.0,Date of first occurrence of G10 (huntington's disease),icd10_g10_date,3 +131015-0.0,Date of first occurrence of G11 (hereditary ataxia),icd10_g11_date,3 +131017-0.0,Date of first occurrence of G12 (spinal muscular atrophy and related syndromes),icd10_g12_date,3 +131019-0.0,Date of first occurrence of G13 (systemic atrophies primarily affecting central nervous system in diseases classified elsewhere),icd10_g13_date,3 +131021-0.0,Date of first occurrence of G14 (postpolio syndrome),icd10_g14_date,3 +131023-0.0,Date of first occurrence of G20 (parkinson's disease),icd10_g20_date,3 +131025-0.0,Date of first occurrence of G21 (secondary parkinsonism),icd10_g21_date,3 +131027-0.0,Date of first occurrence of G22 (parkinsonism in diseases classified elsewhere),icd10_g22_date,3 +131029-0.0,Date of first occurrence of G23 (other degenerative diseases of basal ganglia),icd10_g23_date,3 +131031-0.0,Date of first occurrence of G24 (dystonia),icd10_g24_date,3 +131033-0.0,Date of first occurrence of G25 (other extrapyramidal and movement disorders),icd10_g25_date,3 +131037-0.0,Date of first occurrence of G30 (alzheimer's disease),icd10_g30_date,3 +131039-0.0,"Date of first occurrence of G31 (other degenerative diseases of nervous system, not elsewhere classified)",icd10_g31_date,3 +131041-0.0,Date of first occurrence of G32 (other degenerative disorders of nervous system in diseases classified elsewhere),icd10_g32_date,3 +131043-0.0,Date of first occurrence of G35 (multiple sclerosis),icd10_g35_date,3 +131045-0.0,Date of first occurrence of G36 (other acute disseminated demyelination),icd10_g36_date,3 +131047-0.0,Date of first occurrence of G37 (other demyelinating diseases of central nervous system),icd10_g37_date,3 +131049-0.0,Date of first occurrence of G40 (epilepsy),icd10_g40_date,3 +131051-0.0,Date of first occurrence of G41 (status epilepticus),icd10_g41_date,3 +131053-0.0,Date of first occurrence of G43 (migraine),icd10_g43_date,3 +131055-0.0,Date of first occurrence of G44 (other headache syndromes),icd10_g44_date,3 +131057-0.0,Date of first occurrence of G45 (transient cerebral ischaemic attacks and related syndromes),icd10_g45_date,3 +131059-0.0,Date of first occurrence of G46 (vascular syndromes of brain in cerebrovascular diseases),icd10_g46_date,3 +131061-0.0,Date of first occurrence of G47 (sleep disorders),icd10_g47_date,3 +131063-0.0,Date of first occurrence of G50 (disorders of trigeminal nerve),icd10_g50_date,3 +131065-0.0,Date of first occurrence of G51 (facial nerve disorders),icd10_g51_date,3 +131067-0.0,Date of first occurrence of G52 (disorders of other cranial nerves),icd10_g52_date,3 +131069-0.0,Date of first occurrence of G53 (cranial nerve disorders in diseases classified elsewhere),icd10_g53_date,3 +131071-0.0,Date of first occurrence of G54 (nerve root and plexus disorders),icd10_g54_date,3 +131073-0.0,Date of first occurrence of G55 (nerve root and plexus compressions in diseases classified elsewhere),icd10_g55_date,3 +131075-0.0,Date of first occurrence of G56 (mononeuropathies of upper limb),icd10_g56_date,3 +131077-0.0,Date of first occurrence of G57 (mononeuropathies of lower limb),icd10_g57_date,3 +131079-0.0,Date of first occurrence of G58 (other mononeuropathies),icd10_g58_date,3 +131081-0.0,Date of first occurrence of G59 (mononeuropathy in diseases classified elsewhere),icd10_g59_date,3 +131083-0.0,Date of first occurrence of G60 (hereditary and idiopathic neuropathy),icd10_g60_date,3 +131085-0.0,Date of first occurrence of G61 (inflammatory polyneuropathy),icd10_g61_date,3 +131087-0.0,Date of first occurrence of G62 (other polyneuropathies),icd10_g62_date,3 +131089-0.0,Date of first occurrence of G63 (polyneuropathy in diseases classified elsewhere),icd10_g63_date,3 +131091-0.0,Date of first occurrence of G64 (other disorders of peripheral nervous system),icd10_g64_date,3 +131093-0.0,Date of first occurrence of G70 (myasthenia gravis and other myoneural disorders),icd10_g70_date,3 +131095-0.0,Date of first occurrence of G71 (primary disorders of muscles),icd10_g71_date,3 +131097-0.0,Date of first occurrence of G72 (other myopathies),icd10_g72_date,3 +131099-0.0,Date of first occurrence of G73 (disorders of myoneural junction and muscle in diseases classified elsewhere),icd10_g73_date,3 +131101-0.0,Date of first occurrence of G80 (infantile cerebral palsy),icd10_g80_date,3 +131103-0.0,Date of first occurrence of G81 (hemiplegia),icd10_g81_date,3 +131105-0.0,Date of first occurrence of G82 (paraplegia and tetraplegia),icd10_g82_date,3 +131107-0.0,Date of first occurrence of G83 (other paralytic syndromes),icd10_g83_date,3 +131109-0.0,Date of first occurrence of G90 (disorders of autonomic nervous system),icd10_g90_date,3 +131111-0.0,Date of first occurrence of G91 (hydrocephalus),icd10_g91_date,3 +131113-0.0,Date of first occurrence of G92 (toxic encephalopathy),icd10_g92_date,3 +131115-0.0,Date of first occurrence of G93 (other disorders of brain),icd10_g93_date,3 +131117-0.0,Date of first occurrence of G94 (other disorders of brain in diseases classified elsewhere),icd10_g94_date,3 +131119-0.0,Date of first occurrence of G95 (other diseases of spinal cord),icd10_g95_date,3 +131121-0.0,Date of first occurrence of G96 (other disorders of central nervous system),icd10_g96_date,3 +131123-0.0,"Date of first occurrence of G97 (postprocedural disorders of nervous system, not elsewhere classified)",icd10_g97_date,3 +131125-0.0,"Date of first occurrence of G98 (other disorders of nervous system, not elsewhere classified)",icd10_g98_date,3 +131127-0.0,Date of first occurrence of G99 (other disorders of nervous system in diseases classified elsewhere),icd10_g99_date,3 +131129-0.0,Date of first occurrence of H00 (hordeolum and chalazion),icd10_h00_date,3 +131131-0.0,Date of first occurrence of H01 (other inflammation of eyelid),icd10_h01_date,3 +131133-0.0,Date of first occurrence of H02 (other disorders of eyelid),icd10_h02_date,3 +131135-0.0,Date of first occurrence of H03 (disorders of eyelid in diseases classified elsewhere),icd10_h03_date,3 +131137-0.0,Date of first occurrence of H04 (disorders of lachrymal system),icd10_h04_date,3 +131139-0.0,Date of first occurrence of H05 (disorders of orbit),icd10_h05_date,3 +131141-0.0,Date of first occurrence of H06 (disorders of lachrymal system and orbit in diseases classified elsewhere),icd10_h06_date,3 +131143-0.0,Date of first occurrence of H10 (conjunctivitis),icd10_h10_date,3 +131145-0.0,Date of first occurrence of H11 (other disorders of conjunctiva),icd10_h11_date,3 +131147-0.0,Date of first occurrence of H13 (disorders of conjunctiva in diseases classified elsewhere),icd10_h13_date,3 +131149-0.0,Date of first occurrence of H15 (disorders of sclera),icd10_h15_date,3 +131151-0.0,Date of first occurrence of H16 (keratitis),icd10_h16_date,3 +131153-0.0,Date of first occurrence of H17 (corneal scars and opacities),icd10_h17_date,3 +131155-0.0,Date of first occurrence of H18 (other disorders of cornea),icd10_h18_date,3 +131157-0.0,Date of first occurrence of H19 (disorders of sclera and cornea in diseases classified elsewhere),icd10_h19_date,3 +131159-0.0,Date of first occurrence of H20 (iridocyclitis),icd10_h20_date,3 +131161-0.0,Date of first occurrence of H21 (other disorders of iris and ciliary body),icd10_h21_date,3 +131163-0.0,Date of first occurrence of H22 (disorders of iris and ciliary body in diseases classified elsewhere),icd10_h22_date,3 +131165-0.0,Date of first occurrence of H25 (senile cataract),icd10_h25_date,3 +131167-0.0,Date of first occurrence of H26 (other cataract),icd10_h26_date,3 +131169-0.0,Date of first occurrence of H27 (other disorders of lens),icd10_h27_date,3 +131171-0.0,Date of first occurrence of H28 (cataract and other disorders of lens in diseases classified elsewhere),icd10_h28_date,3 +131173-0.0,Date of first occurrence of H30 (chorioretinal inflammation),icd10_h30_date,3 +131175-0.0,Date of first occurrence of H31 (other disorders of choroid),icd10_h31_date,3 +131177-0.0,Date of first occurrence of H32 (chorioretinal disorders in diseases classified elsewhere),icd10_h32_date,3 +131179-0.0,Date of first occurrence of H33 (retinal detachments and breaks),icd10_h33_date,3 +131181-0.0,Date of first occurrence of H34 (retinal vascular occlusions),icd10_h34_date,3 +131183-0.0,Date of first occurrence of H35 (other retinal disorders),icd10_h35_date,3 +131185-0.0,Date of first occurrence of H36 (retinal disorders in diseases classified elsewhere),icd10_h36_date,3 +131187-0.0,Date of first occurrence of H40 (glaucoma),icd10_h40_date,3 +131189-0.0,Date of first occurrence of H42 (glaucoma in diseases classified elsewhere),icd10_h42_date,3 +131191-0.0,Date of first occurrence of H43 (disorders of vitreous body),icd10_h43_date,3 +131193-0.0,Date of first occurrence of H44 (disorders of globe),icd10_h44_date,3 +131195-0.0,Date of first occurrence of H45 (disorders of vitreous body and globe in diseases classified elsewhere),icd10_h45_date,3 +131197-0.0,Date of first occurrence of H46 (optic neuritis),icd10_h46_date,3 +131199-0.0,Date of first occurrence of H47 (other disorders of optic [2nd] nerve and visual pathways),icd10_h47_date,3 +131201-0.0,Date of first occurrence of H48 (disorders of optic [2nd] nerve and visual pathways in diseases classified elsewhere),icd10_h48_date,3 +131203-0.0,Date of first occurrence of H49 (paralytic strabismus),icd10_h49_date,3 +131205-0.0,Date of first occurrence of H50 (other strabismus),icd10_h50_date,3 +131207-0.0,Date of first occurrence of H51 (other disorders of binocular movement),icd10_h51_date,3 +131209-0.0,Date of first occurrence of H52 (disorders of refraction and accommodation),icd10_h52_date,3 +131211-0.0,Date of first occurrence of H53 (visual disturbances),icd10_h53_date,3 +131213-0.0,Date of first occurrence of H54 (blindness and low vision),icd10_h54_date,3 +131215-0.0,Date of first occurrence of H55 (nystagmus and other irregular eye movements),icd10_h55_date,3 +131217-0.0,Date of first occurrence of H57 (other disorders of eye and adnexa),icd10_h57_date,3 +131219-0.0,Date of first occurrence of H58 (other disorders of eye and adnexa in diseases classified elsewhere),icd10_h58_date,3 +131221-0.0,"Date of first occurrence of H59 (postprocedural disorders of eye and adnexa, not elsewhere classified)",icd10_h59_date,3 +131223-0.0,Date of first occurrence of H60 (otitis externa),icd10_h60_date,3 +131225-0.0,Date of first occurrence of H61 (other disorders of external ear),icd10_h61_date,3 +131227-0.0,Date of first occurrence of H62 (disorders of external ear in diseases classified elsewhere),icd10_h62_date,3 +131229-0.0,Date of first occurrence of H65 (nonsuppurative otitis media),icd10_h65_date,3 +131231-0.0,Date of first occurrence of H66 (suppurative and unspecified otitis media),icd10_h66_date,3 +131233-0.0,Date of first occurrence of H67 (otitis media in diseases classified elsewhere),icd10_h67_date,3 +131235-0.0,Date of first occurrence of H68 (eustachian salpingitis and obstruction),icd10_h68_date,3 +131237-0.0,Date of first occurrence of H69 (other disorders of eustachian tube),icd10_h69_date,3 +131239-0.0,Date of first occurrence of H70 (mastoiditis and related conditions),icd10_h70_date,3 +131241-0.0,Date of first occurrence of H71 (cholesteatoma of middle ear),icd10_h71_date,3 +131243-0.0,Date of first occurrence of H72 (perforation of tympanic membrane),icd10_h72_date,3 +131245-0.0,Date of first occurrence of H73 (other disorders of tympanic membrane),icd10_h73_date,3 +131247-0.0,Date of first occurrence of H74 (other disorders of middle ear and mastoid),icd10_h74_date,3 +131249-0.0,Date of first occurrence of H75 (other disorders of middle ear and mastoid in diseases classified elsewhere),icd10_h75_date,3 +131251-0.0,Date of first occurrence of H80 (otosclerosis),icd10_h80_date,3 +131253-0.0,Date of first occurrence of H81 (disorders of vestibular function),icd10_h81_date,3 +131255-0.0,Date of first occurrence of H82 (vertiginous syndromes in diseases classified elsewhere),icd10_h82_date,3 +131257-0.0,Date of first occurrence of H83 (other diseases of inner ear),icd10_h83_date,3 +131259-0.0,Date of first occurrence of H90 (conductive and sensorineural hearing loss),icd10_h90_date,3 +131261-0.0,Date of first occurrence of H91 (other hearing loss),icd10_h91_date,3 +131263-0.0,Date of first occurrence of H92 (otalgia and effusion of ear),icd10_h92_date,3 +131265-0.0,"Date of first occurrence of H93 (other disorders of ear, not elsewhere classified)",icd10_h93_date,3 +131267-0.0,Date of first occurrence of H94 (other disorders of ear in diseases classified elsewhere),icd10_h94_date,3 +131269-0.0,"Date of first occurrence of H95 (postprocedural disorders of ear and mastoid process, not elsewhere classified)",icd10_h95_date,3 +131271-0.0,Date of first occurrence of I00 (rheumatic fever without mention of heart involvement),icd10_i00_date,3 +131273-0.0,Date of first occurrence of I01 (rheumatic fever with heart involvement),icd10_i01_date,3 +131275-0.0,Date of first occurrence of I02 (rheumatic chorea),icd10_i02_date,3 +131277-0.0,Date of first occurrence of I05 (rheumatic mitral valve diseases),icd10_i05_date,3 +131279-0.0,Date of first occurrence of I06 (rheumatic aortic valve diseases),icd10_i06_date,3 +131281-0.0,Date of first occurrence of I07 (rheumatic tricuspid valve diseases),icd10_i07_date,3 +131283-0.0,Date of first occurrence of I08 (multiple valve diseases),icd10_i08_date,3 +131285-0.0,Date of first occurrence of I09 (other rheumatic heart diseases),icd10_i09_date,3 +131287-0.0,Date of first occurrence of I10 (essential (primary) hypertension),icd10_i10_date,3 +131289-0.0,Date of first occurrence of I11 (hypertensive heart disease),icd10_i11_date,3 +131291-0.0,Date of first occurrence of I12 (hypertensive renal disease),icd10_i12_date,3 +131293-0.0,Date of first occurrence of I13 (hypertensive heart and renal disease),icd10_i13_date,3 +131295-0.0,Date of first occurrence of I15 (secondary hypertension),icd10_i15_date,3 +131297-0.0,Date of first occurrence of I20 (angina pectoris),icd10_i20_date,3 +131299-0.0,Date of first occurrence of I21 (acute myocardial infarction),icd10_i21_date,3 +131301-0.0,Date of first occurrence of I22 (subsequent myocardial infarction),icd10_i22_date,3 +131303-0.0,Date of first occurrence of I23 (certain current complications following acute myocardial infarction),icd10_i23_date,3 +131305-0.0,Date of first occurrence of I24 (other acute ischaemic heart diseases),icd10_i24_date,3 +131307-0.0,Date of first occurrence of I25 (chronic ischaemic heart disease),icd10_i25_date,3 +131309-0.0,Date of first occurrence of I26 (pulmonary embolism),icd10_i26_date,3 +131311-0.0,Date of first occurrence of I27 (other pulmonary heart diseases),icd10_i27_date,3 +131313-0.0,Date of first occurrence of I28 (other diseases of pulmonary vessels),icd10_i28_date,3 +131315-0.0,Date of first occurrence of I30 (acute pericarditis),icd10_i30_date,3 +131317-0.0,Date of first occurrence of I31 (other diseases of pericardium),icd10_i31_date,3 +131319-0.0,Date of first occurrence of I32 (pericarditis in diseases classified elsewhere),icd10_i32_date,3 +131321-0.0,Date of first occurrence of I33 (acute and subacute endocarditis),icd10_i33_date,3 +131323-0.0,Date of first occurrence of I34 (nonrheumatic mitral valve disorders),icd10_i34_date,3 +131325-0.0,Date of first occurrence of I35 (nonrheumatic aortic valve disorders),icd10_i35_date,3 +131327-0.0,Date of first occurrence of I36 (nonrheumatic tricuspid valve disorders),icd10_i36_date,3 +131329-0.0,Date of first occurrence of I37 (pulmonary valve disorders),icd10_i37_date,3 +131331-0.0,"Date of first occurrence of I38 (endocarditis, valve unspecified)",icd10_i38_date,3 +131333-0.0,Date of first occurrence of I39 (endocarditis and heart valve disorders in diseases classified elsewhere),icd10_i39_date,3 +131335-0.0,Date of first occurrence of I40 (acute myocarditis),icd10_i40_date,3 +131337-0.0,Date of first occurrence of I41 (myocarditis in diseases classified elsewhere),icd10_i41_date,3 +131339-0.0,Date of first occurrence of I42 (cardiomyopathy),icd10_i42_date,3 +131341-0.0,Date of first occurrence of I43 (cardiomyopathy in diseases classified elsewhere),icd10_i43_date,3 +131343-0.0,Date of first occurrence of I44 (atrioventricular and left bundle-branch block),icd10_i44_date,3 +131345-0.0,Date of first occurrence of I45 (other conduction disorders),icd10_i45_date,3 +131347-0.0,Date of first occurrence of I46 (cardiac arrest),icd10_i46_date,3 +131349-0.0,Date of first occurrence of I47 (paroxysmal tachycardia),icd10_i47_date,3 +131351-0.0,Date of first occurrence of I48 (atrial fibrillation and flutter),icd10_i48_date,3 +131353-0.0,Date of first occurrence of I49 (other cardiac arrhythmias),icd10_i49_date,3 +131355-0.0,Date of first occurrence of I50 (heart failure),icd10_i50_date,3 +131357-0.0,Date of first occurrence of I51 (complications and ill-defined descriptions of heart disease),icd10_i51_date,3 +131359-0.0,Date of first occurrence of I52 (other heart disorders in diseases classified elsewhere),icd10_i52_date,3 +131361-0.0,Date of first occurrence of I60 (subarachnoid haemorrhage),icd10_i60_date,3 +131363-0.0,Date of first occurrence of I61 (intracerebral haemorrhage),icd10_i61_date,3 +131365-0.0,Date of first occurrence of I62 (other nontraumatic intracranial haemorrhage),icd10_i62_date,3 +131367-0.0,Date of first occurrence of I63 (cerebral infarction),icd10_i63_date,3 +131369-0.0,"Date of first occurrence of I64 (stroke, not specified as haemorrhage or infarction)",icd10_i64_date,3 +131371-0.0,"Date of first occurrence of I65 (occlusion and stenosis of precerebral arteries, not resulting in cerebral infarction)",icd10_i65_date,3 +131373-0.0,"Date of first occurrence of I66 (occlusion and stenosis of cerebral arteries, not resulting in cerebral infarction)",icd10_i66_date,3 +131375-0.0,Date of first occurrence of I67 (other cerebrovascular diseases),icd10_i67_date,3 +131377-0.0,Date of first occurrence of I68 (cerebrovascular disorders in diseases classified elsewhere),icd10_i68_date,3 +131379-0.0,Date of first occurrence of I69 (sequelae of cerebrovascular disease),icd10_i69_date,3 +131381-0.0,Date of first occurrence of I70 (atherosclerosis),icd10_i70_date,3 +131383-0.0,Date of first occurrence of I71 (aortic aneurysm and dissection),icd10_i71_date,3 +131385-0.0,Date of first occurrence of I72 (other aneurysm),icd10_i72_date,3 +131387-0.0,Date of first occurrence of I73 (other peripheral vascular diseases),icd10_i73_date,3 +131389-0.0,Date of first occurrence of I74 (arterial embolism and thrombosis),icd10_i74_date,3 +131391-0.0,Date of first occurrence of I77 (other disorders of arteries and arterioles),icd10_i77_date,3 +131393-0.0,Date of first occurrence of I78 (diseases of capillaries),icd10_i78_date,3 +131395-0.0,"Date of first occurrence of I79 (disorders of arteries, arterioles and capillaries in diseases classified elsewhere)",icd10_i79_date,3 +131397-0.0,Date of first occurrence of I80 (phlebitis and thrombophlebitis),icd10_i80_date,3 +131399-0.0,Date of first occurrence of I81 (portal vein thrombosis),icd10_i81_date,3 +131401-0.0,Date of first occurrence of I82 (other venous embolism and thrombosis),icd10_i82_date,3 +131403-0.0,Date of first occurrence of I83 (varicose veins of lower extremities),icd10_i83_date,3 +131405-0.0,Date of first occurrence of I84 (haemorrhoids),icd10_i84_date,3 +131407-0.0,Date of first occurrence of I85 (oesophageal varices),icd10_i85_date,3 +131409-0.0,Date of first occurrence of I86 (varicose veins of other sites),icd10_i86_date,3 +131411-0.0,Date of first occurrence of I87 (other disorders of veins),icd10_i87_date,3 +131413-0.0,Date of first occurrence of I88 (nonspecific lymphadenitis),icd10_i88_date,3 +131415-0.0,Date of first occurrence of I89 (other non-infective disorders of lymphatic vessels and lymph nodes),icd10_i89_date,3 +131417-0.0,Date of first occurrence of I95 (hypotension),icd10_i95_date,3 +131419-0.0,"Date of first occurrence of I97 (postprocedural disorders of circulatory system, not elsewhere classified)",icd10_i97_date,3 +131421-0.0,Date of first occurrence of I98 (other disorders of circulatory system in diseases classified elsewhere),icd10_i98_date,3 +131423-0.0,Date of first occurrence of I99 (other and unspecified disorders of circulatory system),icd10_i99_date,3 +131425-0.0,Date of first occurrence of J00 (acute nasopharyngitis [common cold]),icd10_j00_date,3 +131427-0.0,Date of first occurrence of J01 (acute sinusitis),icd10_j01_date,3 +131429-0.0,Date of first occurrence of J02 (acute pharyngitis),icd10_j02_date,3 +131431-0.0,Date of first occurrence of J03 (acute tonsillitis),icd10_j03_date,3 +131433-0.0,Date of first occurrence of J04 (acute laryngitis and tracheitis),icd10_j04_date,3 +131435-0.0,Date of first occurrence of J05 (acute obstructive laryngitis [croup] and epiglottitis),icd10_j05_date,3 +131437-0.0,Date of first occurrence of J06 (acute upper respiratory infections of multiple and unspecified sites),icd10_j06_date,3 +131439-0.0,Date of first occurrence of J09 (influenza due to certain identified influenza virus),icd10_j09_date,3 +131441-0.0,Date of first occurrence of J10 (influenza due to identified influenza virus),icd10_j10_date,3 +131443-0.0,"Date of first occurrence of J11 (influenza, virus not identified)",icd10_j11_date,3 +131445-0.0,"Date of first occurrence of J12 (viral pneumonia, not elsewhere classified)",icd10_j12_date,3 +131447-0.0,Date of first occurrence of J13 (pneumonia due to streptococcus pneumoniae),icd10_j13_date,3 +131449-0.0,Date of first occurrence of J14 (pneumonia due to haemophilus influenzae),icd10_j14_date,3 +131451-0.0,"Date of first occurrence of J15 (bacterial pneumonia, not elsewhere classified)",icd10_j15_date,3 +131453-0.0,"Date of first occurrence of J16 (pneumonia due to other infectious organisms, not elsewhere classified)",icd10_j16_date,3 +131455-0.0,Date of first occurrence of J17 (pneumonia in diseases classified elsewhere),icd10_j17_date,3 +131457-0.0,"Date of first occurrence of J18 (pneumonia, organism unspecified)",icd10_j18_date,3 +131459-0.0,Date of first occurrence of J20 (acute bronchitis),icd10_j20_date,3 +131461-0.0,Date of first occurrence of J21 (acute bronchiolitis),icd10_j21_date,3 +131463-0.0,Date of first occurrence of J22 (unspecified acute lower respiratory infection),icd10_j22_date,3 +131465-0.0,Date of first occurrence of J30 (vasomotor and allergic rhinitis),icd10_j30_date,3 +131467-0.0,"Date of first occurrence of J31 (chronic rhinitis, nasopharyngitis and pharyngitis)",icd10_j31_date,3 +131469-0.0,Date of first occurrence of J32 (chronic sinusitis),icd10_j32_date,3 +131471-0.0,Date of first occurrence of J33 (nasal polyp),icd10_j33_date,3 +131473-0.0,Date of first occurrence of J34 (other disorders of nose and nasal sinuses),icd10_j34_date,3 +131475-0.0,Date of first occurrence of J35 (chronic diseases of tonsils and adenoids),icd10_j35_date,3 +131477-0.0,Date of first occurrence of J36 (peritonsillar abscess),icd10_j36_date,3 +131479-0.0,Date of first occurrence of J37 (chronic laryngitis and laryngotracheitis),icd10_j37_date,3 +131481-0.0,"Date of first occurrence of J38 (diseases of vocal cords and larynx, not elsewhere classified)",icd10_j38_date,3 +131483-0.0,Date of first occurrence of J39 (other diseases of upper respiratory tract),icd10_j39_date,3 +131485-0.0,"Date of first occurrence of J40 (bronchitis, not specified as acute or chronic)",icd10_j40_date,3 +131487-0.0,Date of first occurrence of J41 (simple and mucopurulent chronic bronchitis),icd10_j41_date,3 +131489-0.0,Date of first occurrence of J42 (unspecified chronic bronchitis),icd10_j42_date,3 +131491-0.0,Date of first occurrence of J43 (emphysema),icd10_j43_date,3 +131493-0.0,Date of first occurrence of J44 (other chronic obstructive pulmonary disease),icd10_j44_date,3 +131495-0.0,Date of first occurrence of J45 (asthma),icd10_j45_date,3 +131497-0.0,Date of first occurrence of J46 (status asthmaticus),icd10_j46_date,3 +131499-0.0,Date of first occurrence of J47 (bronchiectasis),icd10_j47_date,3 +131501-0.0,Date of first occurrence of J60 (coalworker's pneumoconiosis),icd10_j60_date,3 +131503-0.0,Date of first occurrence of J61 (pneumoconiosis due to asbestos and other mineral fibres),icd10_j61_date,3 +131505-0.0,Date of first occurrence of J62 (pneumoconiosis due to dust containing silica),icd10_j62_date,3 +131507-0.0,Date of first occurrence of J63 (pneumoconiosis due to other inorganic dusts),icd10_j63_date,3 +131509-0.0,Date of first occurrence of J64 (unspecified pneumoconiosis),icd10_j64_date,3 +131513-0.0,Date of first occurrence of J66 (airway disease due to specific organic dust),icd10_j66_date,3 +131515-0.0,Date of first occurrence of J67 (hypersensitivity pneumonitis due to organic dust),icd10_j67_date,3 +131517-0.0,"Date of first occurrence of J68 (respiratory conditions due to inhalation of chemicals, gases, fumes and vapours)",icd10_j68_date,3 +131519-0.0,Date of first occurrence of J69 (pneumonitis due to solids and liquids),icd10_j69_date,3 +131521-0.0,Date of first occurrence of J70 (respiratory conditions due to other external agents),icd10_j70_date,3 +131523-0.0,Date of first occurrence of J80 (adult respiratory distress syndrome),icd10_j80_date,3 +131525-0.0,Date of first occurrence of J81 (pulmonary oedema),icd10_j81_date,3 +131527-0.0,"Date of first occurrence of J82 (pulmonary eosinophilia, not elsewhere classified)",icd10_j82_date,3 +131529-0.0,Date of first occurrence of J84 (other interstitial pulmonary diseases),icd10_j84_date,3 +131531-0.0,Date of first occurrence of J85 (abscess of lung and mediastinum),icd10_j85_date,3 +131533-0.0,Date of first occurrence of J86 (pyothorax),icd10_j86_date,3 +131535-0.0,"Date of first occurrence of J90 (pleural effusion, not elsewhere classified)",icd10_j90_date,3 +131537-0.0,Date of first occurrence of J91 (pleural effusion in conditions classified elsewhere),icd10_j91_date,3 +131539-0.0,Date of first occurrence of J92 (pleural plaque),icd10_j92_date,3 +131541-0.0,Date of first occurrence of J93 (pneumothorax),icd10_j93_date,3 +131543-0.0,Date of first occurrence of J94 (other pleural conditions),icd10_j94_date,3 +131545-0.0,"Date of first occurrence of J95 (postprocedural respiratory disorders, not elsewhere classified)",icd10_j95_date,3 +131547-0.0,"Date of first occurrence of J96 (respiratory failure, not elsewhere classified)",icd10_j96_date,3 +131549-0.0,Date of first occurrence of J98 (other respiratory disorders),icd10_j98_date,3 +131551-0.0,Date of first occurrence of J99 (respiratory disorders in diseases classified elsewhere),icd10_j99_date,3 +131553-0.0,Date of first occurrence of K00 (disorders of tooth development and eruption),icd10_k00_date,3 +131555-0.0,Date of first occurrence of K01 (embedded and impacted teeth),icd10_k01_date,3 +131557-0.0,Date of first occurrence of K02 (dental caries),icd10_k02_date,3 +131559-0.0,Date of first occurrence of K03 (other diseases of hard tissues of teeth),icd10_k03_date,3 +131561-0.0,Date of first occurrence of K04 (diseases of pulp and periapical tissues),icd10_k04_date,3 +131563-0.0,Date of first occurrence of K05 (gingivitis and periodontal diseases),icd10_k05_date,3 +131565-0.0,Date of first occurrence of K06 (other disorders of gingiva and edentulous alveolar ridge),icd10_k06_date,3 +131567-0.0,Date of first occurrence of K07 (dentofacial anomalies [including malocclusion]),icd10_k07_date,3 +131569-0.0,Date of first occurrence of K08 (other disorders of teeth and supporting structures),icd10_k08_date,3 +131571-0.0,"Date of first occurrence of K09 (cysts of oral region, not elsewhere classified)",icd10_k09_date,3 +131573-0.0,Date of first occurrence of K10 (other diseases of jaws),icd10_k10_date,3 +131575-0.0,Date of first occurrence of K11 (diseases of salivary glands),icd10_k11_date,3 +131577-0.0,Date of first occurrence of K12 (stomatitis and related lesions),icd10_k12_date,3 +131579-0.0,Date of first occurrence of K13 (other diseases of lip and oral mucosa),icd10_k13_date,3 +131581-0.0,Date of first occurrence of K14 (diseases of tongue),icd10_k14_date,3 +131583-0.0,Date of first occurrence of K20 (oesophagitis),icd10_k20_date,3 +131585-0.0,Date of first occurrence of K21 (gastro-oesophageal reflux disease),icd10_k21_date,3 +131587-0.0,Date of first occurrence of K22 (other diseases of oesophagus),icd10_k22_date,3 +131589-0.0,Date of first occurrence of K23 (disorders of oesophagus in diseases classified elsewhere),icd10_k23_date,3 +131591-0.0,Date of first occurrence of K25 (gastric ulcer),icd10_k25_date,3 +131593-0.0,Date of first occurrence of K26 (duodenal ulcer),icd10_k26_date,3 +131595-0.0,"Date of first occurrence of K27 (peptic ulcer, site unspecified)",icd10_k27_date,3 +131597-0.0,Date of first occurrence of K28 (gastrojejunal ulcer),icd10_k28_date,3 +131599-0.0,Date of first occurrence of K29 (gastritis and duodenitis),icd10_k29_date,3 +131601-0.0,Date of first occurrence of K30 (dyspepsia),icd10_k30_date,3 +131603-0.0,Date of first occurrence of K31 (other diseases of stomach and duodenum),icd10_k31_date,3 +131605-0.0,Date of first occurrence of K35 (acute appendicitis),icd10_k35_date,3 +131607-0.0,Date of first occurrence of K36 (other appendicitis),icd10_k36_date,3 +131609-0.0,Date of first occurrence of K37 (unspecified appendicitis),icd10_k37_date,3 +131611-0.0,Date of first occurrence of K38 (other diseases of appendix),icd10_k38_date,3 +131613-0.0,Date of first occurrence of K40 (inguinal hernia),icd10_k40_date,3 +131615-0.0,Date of first occurrence of K41 (femoral hernia),icd10_k41_date,3 +131617-0.0,Date of first occurrence of K42 (umbilical hernia),icd10_k42_date,3 +131619-0.0,Date of first occurrence of K43 (ventral hernia),icd10_k43_date,3 +131621-0.0,Date of first occurrence of K44 (diaphragmatic hernia),icd10_k44_date,3 +131623-0.0,Date of first occurrence of K45 (other abdominal hernia),icd10_k45_date,3 +131625-0.0,Date of first occurrence of K46 (unspecified abdominal hernia),icd10_k46_date,3 +131627-0.0,Date of first occurrence of K50 (crohn's disease [regional enteritis]),icd10_k50_date,3 +131629-0.0,Date of first occurrence of K51 (ulcerative colitis),icd10_k51_date,3 +131631-0.0,Date of first occurrence of K52 (other non-infective gastro-enteritis and colitis),icd10_k52_date,3 +131633-0.0,Date of first occurrence of K55 (vascular disorders of intestine),icd10_k55_date,3 +131635-0.0,Date of first occurrence of K56 (paralytic ileus and intestinal obstruction without hernia),icd10_k56_date,3 +131637-0.0,Date of first occurrence of K57 (diverticular disease of intestine),icd10_k57_date,3 +131639-0.0,Date of first occurrence of K58 (irritable bowel syndrome),icd10_k58_date,3 +131641-0.0,Date of first occurrence of K59 (other functional intestinal disorders),icd10_k59_date,3 +131643-0.0,Date of first occurrence of K60 (fissure and fistula of anal and rectal regions),icd10_k60_date,3 +131645-0.0,Date of first occurrence of K61 (abscess of anal and rectal regions),icd10_k61_date,3 +131647-0.0,Date of first occurrence of K62 (other diseases of anus and rectum),icd10_k62_date,3 +131649-0.0,Date of first occurrence of K63 (other diseases of intestine),icd10_k63_date,3 +131651-0.0,Date of first occurrence of K64 (haemorrhoids and perianal venous thrombosis),icd10_k64_date,3 +131653-0.0,Date of first occurrence of K65 (peritonitis),icd10_k65_date,3 +131655-0.0,Date of first occurrence of K66 (other disorders of peritoneum),icd10_k66_date,3 +131657-0.0,Date of first occurrence of K67 (disorders of peritoneum in infectious diseases classified elsewhere),icd10_k67_date,3 +131659-0.0,Date of first occurrence of K70 (alcoholic liver disease),icd10_k70_date,3 +131661-0.0,Date of first occurrence of K71 (toxic liver disease),icd10_k71_date,3 +131663-0.0,"Date of first occurrence of K72 (hepatic failure, not elsewhere classified)",icd10_k72_date,3 +131665-0.0,"Date of first occurrence of K73 (chronic hepatitis, not elsewhere classified)",icd10_k73_date,3 +131667-0.0,Date of first occurrence of K74 (fibrosis and cirrhosis of liver),icd10_k74_date,3 +131669-0.0,Date of first occurrence of K75 (other inflammatory liver diseases),icd10_k75_date,3 +131671-0.0,Date of first occurrence of K76 (other diseases of liver),icd10_k76_date,3 +131673-0.0,Date of first occurrence of K77 (liver disorders in diseases classified elsewhere),icd10_k77_date,3 +131675-0.0,Date of first occurrence of K80 (cholelithiasis),icd10_k80_date,3 +131677-0.0,Date of first occurrence of K81 (cholecystitis),icd10_k81_date,3 +131679-0.0,Date of first occurrence of K82 (other diseases of gallbladder),icd10_k82_date,3 +131681-0.0,Date of first occurrence of K83 (other diseases of biliary tract),icd10_k83_date,3 +131683-0.0,Date of first occurrence of K85 (acute pancreatitis),icd10_k85_date,3 +131685-0.0,Date of first occurrence of K86 (other diseases of pancreas),icd10_k86_date,3 +131687-0.0,"Date of first occurrence of K87 (disorders of gallbladder, biliary tract and pancreas in diseases classified elsewhere)",icd10_k87_date,3 +131689-0.0,Date of first occurrence of K90 (intestinal malabsorption),icd10_k90_date,3 +131691-0.0,"Date of first occurrence of K91 (postprocedural disorders of digestive system, not elsewhere classified)",icd10_k91_date,3 +131693-0.0,Date of first occurrence of K92 (other diseases of digestive system),icd10_k92_date,3 +131695-0.0,Date of first occurrence of K93 (disorders of other digestive organs in diseases classified elsewhere),icd10_k93_date,3 +131697-0.0,Date of first occurrence of L00 (staphylococcal scalded skin syndrome),icd10_l00_date,3 +131699-0.0,Date of first occurrence of L01 (impetigo),icd10_l01_date,3 +131701-0.0,"Date of first occurrence of L02 (cutaneous abscess, furuncle and carbuncle)",icd10_l02_date,3 +131703-0.0,Date of first occurrence of L03 (cellulitis),icd10_l03_date,3 +131705-0.0,Date of first occurrence of L04 (acute lymphadenitis),icd10_l04_date,3 +131707-0.0,Date of first occurrence of L05 (pilonidal cyst),icd10_l05_date,3 +131709-0.0,Date of first occurrence of L08 (other local infections of skin and subcutaneous tissue),icd10_l08_date,3 +131711-0.0,Date of first occurrence of L10 (pemphigus),icd10_l10_date,3 +131713-0.0,Date of first occurrence of L11 (other acantholytic disorders),icd10_l11_date,3 +131715-0.0,Date of first occurrence of L12 (pemphigoid),icd10_l12_date,3 +131717-0.0,Date of first occurrence of L13 (other bullous disorders),icd10_l13_date,3 +131719-0.0,Date of first occurrence of L14 (bullous disorders in diseases classified elsewhere),icd10_l14_date,3 +131721-0.0,Date of first occurrence of L20 (atopic dermatitis),icd10_l20_date,3 +131723-0.0,Date of first occurrence of L21 (seborrhoeic dermatitis),icd10_l21_date,3 +131725-0.0,Date of first occurrence of L22 (diaper [napkin] dermatitis),icd10_l22_date,3 +131727-0.0,Date of first occurrence of L23 (allergic contact dermatitis),icd10_l23_date,3 +131729-0.0,Date of first occurrence of L24 (irritant contact dermatitis),icd10_l24_date,3 +131731-0.0,Date of first occurrence of L25 (unspecified contact dermatitis),icd10_l25_date,3 +131733-0.0,Date of first occurrence of L26 (exfoliative dermatitis),icd10_l26_date,3 +131735-0.0,Date of first occurrence of L27 (dermatitis due to substances taken internally),icd10_l27_date,3 +131737-0.0,Date of first occurrence of L28 (lichen simplex chronicus and prurigo),icd10_l28_date,3 +131739-0.0,Date of first occurrence of L29 (pruritus),icd10_l29_date,3 +131741-0.0,Date of first occurrence of L30 (other dermatitis),icd10_l30_date,3 +131743-0.0,Date of first occurrence of L40 (psoriasis),icd10_l40_date,3 +131745-0.0,Date of first occurrence of L41 (parapsoriasis),icd10_l41_date,3 +131747-0.0,Date of first occurrence of L42 (pityriasis rosea),icd10_l42_date,3 +131749-0.0,Date of first occurrence of L43 (lichen planus),icd10_l43_date,3 +131751-0.0,Date of first occurrence of L44 (other papulosquamous disorders),icd10_l44_date,3 +131755-0.0,Date of first occurrence of L50 (urticaria),icd10_l50_date,3 +131757-0.0,Date of first occurrence of L51 (erythema multiforme),icd10_l51_date,3 +131759-0.0,Date of first occurrence of L52 (erythema nodosum),icd10_l52_date,3 +131761-0.0,Date of first occurrence of L53 (other erythematous conditions),icd10_l53_date,3 +131763-0.0,Date of first occurrence of L54 (erythema in diseases classified elsewhere),icd10_l54_date,3 +131765-0.0,Date of first occurrence of L55 (sunburn),icd10_l55_date,3 +131767-0.0,Date of first occurrence of L56 (other acute skin changes due to ultraviolet radiation),icd10_l56_date,3 +131769-0.0,Date of first occurrence of L57 (skin changes due to chronic exposure to nonionising radiation),icd10_l57_date,3 +131771-0.0,Date of first occurrence of L58 (radiodermatitis),icd10_l58_date,3 +131773-0.0,Date of first occurrence of L59 (other disorders of skin and subcutaneous tissue related to radiation),icd10_l59_date,3 +131775-0.0,Date of first occurrence of L60 (nail disorders),icd10_l60_date,3 +131777-0.0,Date of first occurrence of L62 (nail disorders in diseases classified elsewhere),icd10_l62_date,3 +131779-0.0,Date of first occurrence of L63 (alopecia areata),icd10_l63_date,3 +131781-0.0,Date of first occurrence of L64 (androgenic alopecia),icd10_l64_date,3 +131783-0.0,Date of first occurrence of L65 (other nonscarring hair loss),icd10_l65_date,3 +131785-0.0,Date of first occurrence of L66 (cicatricial alopecia [scarring hair loss]),icd10_l66_date,3 +131787-0.0,Date of first occurrence of L67 (hair colour and hair shaft abnormalities),icd10_l67_date,3 +131789-0.0,Date of first occurrence of L68 (hypertrichosis),icd10_l68_date,3 +131791-0.0,Date of first occurrence of L70 (acne),icd10_l70_date,3 +131793-0.0,Date of first occurrence of L71 (rosacea),icd10_l71_date,3 +131795-0.0,Date of first occurrence of L72 (follicular cysts of skin and subcutaneous tissue),icd10_l72_date,3 +131797-0.0,Date of first occurrence of L73 (other follicular disorders),icd10_l73_date,3 +131799-0.0,Date of first occurrence of L74 (eccrine sweat disorders),icd10_l74_date,3 +131801-0.0,Date of first occurrence of L75 (apocrine sweat disorders),icd10_l75_date,3 +131803-0.0,Date of first occurrence of L80 (vitiligo),icd10_l80_date,3 +131805-0.0,Date of first occurrence of L81 (other disorders of pigmentation),icd10_l81_date,3 +131807-0.0,Date of first occurrence of L82 (seborrhoeic keratosis),icd10_l82_date,3 +131809-0.0,Date of first occurrence of L83 (acanthosis nigricans),icd10_l83_date,3 +131811-0.0,Date of first occurrence of L84 (corns and callosities),icd10_l84_date,3 +131813-0.0,Date of first occurrence of L85 (other epidermal thickening),icd10_l85_date,3 +131815-0.0,Date of first occurrence of L86 (keratoderma in diseases classified elsewhere),icd10_l86_date,3 +131817-0.0,Date of first occurrence of L87 (transepidermal elimination disorders),icd10_l87_date,3 +131819-0.0,Date of first occurrence of L88 (pyoderma gangrenosum),icd10_l88_date,3 +131821-0.0,Date of first occurrence of L89 (decubitus ulcer),icd10_l89_date,3 +131823-0.0,Date of first occurrence of L90 (atrophic disorders of skin),icd10_l90_date,3 +131825-0.0,Date of first occurrence of L91 (hypertrophic disorders of skin),icd10_l91_date,3 +131827-0.0,Date of first occurrence of L92 (granulomatous disorders of skin and subcutaneous tissue),icd10_l92_date,3 +131829-0.0,Date of first occurrence of L93 (lupus erythematosus),icd10_l93_date,3 +131831-0.0,Date of first occurrence of L94 (other localised connective tissue disorders),icd10_l94_date,3 +131833-0.0,"Date of first occurrence of L95 (vasculitis limited to skin, not elsewhere classified)",icd10_l95_date,3 +131835-0.0,"Date of first occurrence of L97 (ulcer of lower limb, not elsewhere classified)",icd10_l97_date,3 +131837-0.0,"Date of first occurrence of L98 (other disorders of skin and subcutaneous tissue, not elsewhere classified)",icd10_l98_date,3 +131839-0.0,Date of first occurrence of L99 (other disorders of skin and subcutaneous tissue in diseases classified elsewhere),icd10_l99_date,3 +131841-0.0,Date of first occurrence of M00 (pyogenic arthritis),icd10_m00_date,3 +131843-0.0,Date of first occurrence of M01 (direct infections of joint in infectious and parasitic diseases classified elsewhere),icd10_m01_date,3 +131845-0.0,Date of first occurrence of M02 (reactive arthropathies),icd10_m02_date,3 +131847-0.0,Date of first occurrence of M03 (postinfective and reactive arthropathies in diseases classified elsewhere),icd10_m03_date,3 +131849-0.0,Date of first occurrence of M05 (seropositive rheumatoid arthritis),icd10_m05_date,3 +131851-0.0,Date of first occurrence of M06 (other rheumatoid arthritis),icd10_m06_date,3 +131853-0.0,Date of first occurrence of M07 (psoriatic and enteropathic arthropathies),icd10_m07_date,3 +131855-0.0,Date of first occurrence of M08 (juvenile arthritis),icd10_m08_date,3 +131857-0.0,Date of first occurrence of M09 (juvenile arthritis in diseases classified elsewhere),icd10_m09_date,3 +131859-0.0,Date of first occurrence of M10 (gout),icd10_m10_date,3 +131861-0.0,Date of first occurrence of M11 (other crystal arthropathies),icd10_m11_date,3 +131863-0.0,Date of first occurrence of M12 (other specific arthropathies),icd10_m12_date,3 +131865-0.0,Date of first occurrence of M13 (other arthritis),icd10_m13_date,3 +131867-0.0,Date of first occurrence of M14 (arthropathies in other diseases classified elsewhere),icd10_m14_date,3 +131869-0.0,Date of first occurrence of M15 (polyarthrosis),icd10_m15_date,3 +131871-0.0,Date of first occurrence of M16 (coxarthrosis [arthrosis of hip]),icd10_m16_date,3 +131873-0.0,Date of first occurrence of M17 (gonarthrosis [arthrosis of knee]),icd10_m17_date,3 +131875-0.0,Date of first occurrence of M18 (arthrosis of first carpometacarpal joint),icd10_m18_date,3 +131877-0.0,Date of first occurrence of M19 (other arthrosis),icd10_m19_date,3 +131879-0.0,Date of first occurrence of M20 (acquired deformities of fingers and toes),icd10_m20_date,3 +131881-0.0,Date of first occurrence of M21 (other acquired deformities of limbs),icd10_m21_date,3 +131883-0.0,Date of first occurrence of M22 (disorders of patella),icd10_m22_date,3 +131885-0.0,Date of first occurrence of M23 (internal derangement of knee),icd10_m23_date,3 +131887-0.0,Date of first occurrence of M24 (other specific joint derangements),icd10_m24_date,3 +131889-0.0,"Date of first occurrence of M25 (other joint disorders, not elsewhere classified)",icd10_m25_date,3 +131891-0.0,Date of first occurrence of M30 (polyarteritis nodosa and related conditions),icd10_m30_date,3 +131893-0.0,Date of first occurrence of M31 (other necrotising vasculopathies),icd10_m31_date,3 +131895-0.0,Date of first occurrence of M32 (systemic lupus erythematosus),icd10_m32_date,3 +131897-0.0,Date of first occurrence of M33 (dermatopolymyositis),icd10_m33_date,3 +131899-0.0,Date of first occurrence of M34 (systemic sclerosis),icd10_m34_date,3 +131901-0.0,Date of first occurrence of M35 (other systemic involvement of connective tissue),icd10_m35_date,3 +131903-0.0,Date of first occurrence of M36 (systemic disorders of connective tissue in diseases classified elsewhere),icd10_m36_date,3 +131905-0.0,Date of first occurrence of M40 (kyphosis and lordosis),icd10_m40_date,3 +131907-0.0,Date of first occurrence of M41 (scoliosis),icd10_m41_date,3 +131909-0.0,Date of first occurrence of M42 (spinal osteochondrosis),icd10_m42_date,3 +131911-0.0,Date of first occurrence of M43 (other deforming dorsopathies),icd10_m43_date,3 +131913-0.0,Date of first occurrence of M45 (ankylosing spondylitis),icd10_m45_date,3 +131915-0.0,Date of first occurrence of M46 (other inflammatory spondylopathies),icd10_m46_date,3 +131917-0.0,Date of first occurrence of M47 (spondylosis),icd10_m47_date,3 +131919-0.0,Date of first occurrence of M48 (other spondylopathies),icd10_m48_date,3 +131921-0.0,Date of first occurrence of M49 (spondylopathies in diseases classified elsewhere),icd10_m49_date,3 +131923-0.0,Date of first occurrence of M50 (cervical disk disorders),icd10_m50_date,3 +131925-0.0,Date of first occurrence of M51 (other intervertebral disk disorders),icd10_m51_date,3 +131927-0.0,"Date of first occurrence of M53 (other dorsopathies, not elsewhere classified)",icd10_m53_date,3 +131929-0.0,Date of first occurrence of M54 (dorsalgia),icd10_m54_date,3 +131931-0.0,Date of first occurrence of M60 (myositis),icd10_m60_date,3 +131933-0.0,Date of first occurrence of M61 (calcification and ossification of muscle),icd10_m61_date,3 +131935-0.0,Date of first occurrence of M62 (other disorders of muscle),icd10_m62_date,3 +131937-0.0,Date of first occurrence of M63 (disorders of muscle in diseases classified elsewhere),icd10_m63_date,3 +131939-0.0,Date of first occurrence of M65 (synovitis and tenosynovitis),icd10_m65_date,3 +131941-0.0,Date of first occurrence of M66 (spontaneous rupture of synovium and tendon),icd10_m66_date,3 +131943-0.0,Date of first occurrence of M67 (other disorders of synovium and tendon),icd10_m67_date,3 +131945-0.0,Date of first occurrence of M68 (disorders of synovium and tendon in diseases classified elsewhere),icd10_m68_date,3 +131947-0.0,"Date of first occurrence of M70 (soft tissue disorders related to use, overuse and pressure)",icd10_m70_date,3 +131949-0.0,Date of first occurrence of M71 (other bursopathies),icd10_m71_date,3 +131951-0.0,Date of first occurrence of M72 (fibroblastic disorders),icd10_m72_date,3 +131953-0.0,Date of first occurrence of M73 (soft tissue disorders in diseases classified elsewhere),icd10_m73_date,3 +131955-0.0,Date of first occurrence of M75 (shoulder lesions),icd10_m75_date,3 +131957-0.0,"Date of first occurrence of M76 (enthesopathies of lower limb, excluding foot)",icd10_m76_date,3 +131959-0.0,Date of first occurrence of M77 (other enthesopathies),icd10_m77_date,3 +131961-0.0,"Date of first occurrence of M79 (other soft tissue disorders, not elsewhere classified)",icd10_m79_date,3 +131963-0.0,Date of first occurrence of M80 (osteoporosis with pathological fracture),icd10_m80_date,3 +131965-0.0,Date of first occurrence of M81 (osteoporosis without pathological fracture),icd10_m81_date,3 +131967-0.0,Date of first occurrence of M82 (osteoporosis in diseases classified elsewhere),icd10_m82_date,3 +131969-0.0,Date of first occurrence of M83 (adult osteomalacia),icd10_m83_date,3 +131971-0.0,Date of first occurrence of M84 (disorders of continuity of bone),icd10_m84_date,3 +131973-0.0,Date of first occurrence of M85 (other disorders of bone density and structure),icd10_m85_date,3 +131975-0.0,Date of first occurrence of M86 (osteomyelitis),icd10_m86_date,3 +131977-0.0,Date of first occurrence of M87 (osteonecrosis),icd10_m87_date,3 +131979-0.0,Date of first occurrence of M88 (paget's disease of bone [osteitis deformans]),icd10_m88_date,3 +131981-0.0,Date of first occurrence of M89 (other disorders of bone),icd10_m89_date,3 +131983-0.0,Date of first occurrence of M90 (osteopathies in diseases classified elsewhere),icd10_m90_date,3 +131985-0.0,Date of first occurrence of M91 (juvenile osteochondrosis of hip and pelvis),icd10_m91_date,3 +131987-0.0,Date of first occurrence of M92 (other juvenile osteochondrosis),icd10_m92_date,3 +131989-0.0,Date of first occurrence of M93 (other osteochondropathies),icd10_m93_date,3 +131991-0.0,Date of first occurrence of M94 (other disorders of cartilage),icd10_m94_date,3 +131993-0.0,Date of first occurrence of M95 (other acquired deformities of musculoskeletal system and connective tissue),icd10_m95_date,3 +131995-0.0,"Date of first occurrence of M96 (postprocedural musculoskeletal disorders, not elsewhere classified)",icd10_m96_date,3 +131997-0.0,"Date of first occurrence of M99 (biomechanical lesions, not elsewhere classified)",icd10_m99_date,3 +131999-0.0,Date of first occurrence of N00 (acute nephritic syndrome),icd10_n00_date,3 +132001-0.0,Date of first occurrence of N01 (rapidly progressive nephritic syndrome),icd10_n01_date,3 +132003-0.0,Date of first occurrence of N02 (recurrent and persistent haematuria),icd10_n02_date,3 +132005-0.0,Date of first occurrence of N03 (chronic nephritic syndrome),icd10_n03_date,3 +132007-0.0,Date of first occurrence of N04 (nephrotic syndrome),icd10_n04_date,3 +132009-0.0,Date of first occurrence of N05 (unspecified nephritic syndrome),icd10_n05_date,3 +132011-0.0,Date of first occurrence of N06 (isolated proteinuria with specified morphological lesion),icd10_n06_date,3 +132013-0.0,"Date of first occurrence of N07 (hereditary nephropathy, not elsewhere classified)",icd10_n07_date,3 +132015-0.0,Date of first occurrence of N08 (glomerular disorders in diseases classified elsewhere),icd10_n08_date,3 +132017-0.0,Date of first occurrence of N10 (acute tubulo-interstitial nephritis),icd10_n10_date,3 +132019-0.0,Date of first occurrence of N11 (chronic tubulo-interstitial nephritis),icd10_n11_date,3 +132021-0.0,"Date of first occurrence of N12 (tubulo-interstitial nephritis, not specified as acute or chronic)",icd10_n12_date,3 +132023-0.0,Date of first occurrence of N13 (obstructive and reflux uropathy),icd10_n13_date,3 +132025-0.0,Date of first occurrence of N14 (drug- and heavy-metal-induced tubulo-interstitial and tubular conditions),icd10_n14_date,3 +132027-0.0,Date of first occurrence of N15 (other renal tubulo-interstitial diseases),icd10_n15_date,3 +132029-0.0,Date of first occurrence of N16 (renal tubulo-interstitial disorders in diseases classified elsewhere),icd10_n16_date,3 +132031-0.0,Date of first occurrence of N17 (acute renal failure),icd10_n17_date,3 +132033-0.0,Date of first occurrence of N18 (chronic renal failure),icd10_n18_date,3 +132035-0.0,Date of first occurrence of N19 (unspecified renal failure),icd10_n19_date,3 +132037-0.0,Date of first occurrence of N20 (calculus of kidney and ureter),icd10_n20_date,3 +132039-0.0,Date of first occurrence of N21 (calculus of lower urinary tract),icd10_n21_date,3 +132041-0.0,Date of first occurrence of N22 (calculus of urinary tract in diseases classified elsewhere),icd10_n22_date,3 +132043-0.0,Date of first occurrence of N23 (unspecified renal colic),icd10_n23_date,3 +132045-0.0,Date of first occurrence of N25 (disorders resulting from impaired renal tubular function),icd10_n25_date,3 +132047-0.0,Date of first occurrence of N26 (unspecified contracted kidney),icd10_n26_date,3 +132049-0.0,Date of first occurrence of N27 (small kidney of unknown cause),icd10_n27_date,3 +132051-0.0,"Date of first occurrence of N28 (other disorders of kidney and ureter, not elsewhere classified)",icd10_n28_date,3 +132053-0.0,Date of first occurrence of N29 (other disorders of kidney and ureter in diseases classified elsewhere),icd10_n29_date,3 +132055-0.0,Date of first occurrence of N30 (cystitis),icd10_n30_date,3 +132057-0.0,"Date of first occurrence of N31 (neuromuscular dysfunction of bladder, not elsewhere classified)",icd10_n31_date,3 +132059-0.0,Date of first occurrence of N32 (other disorders of bladder),icd10_n32_date,3 +132061-0.0,Date of first occurrence of N33 (bladder disorders in diseases classified elsewhere),icd10_n33_date,3 +132063-0.0,Date of first occurrence of N34 (urethritis and urethral syndrome),icd10_n34_date,3 +132065-0.0,Date of first occurrence of N35 (urethral stricture),icd10_n35_date,3 +132067-0.0,Date of first occurrence of N36 (other disorders of urethra),icd10_n36_date,3 +132069-0.0,Date of first occurrence of N37 (urethral disorders in diseases classified elsewhere),icd10_n37_date,3 +132071-0.0,Date of first occurrence of N39 (other disorders of urinary system),icd10_n39_date,3 +132073-0.0,Date of first occurrence of N40 (hyperplasia of prostate),icd10_n40_date,3 +132075-0.0,Date of first occurrence of N41 (inflammatory diseases of prostate),icd10_n41_date,3 +132077-0.0,Date of first occurrence of N42 (other disorders of prostate),icd10_n42_date,3 +132079-0.0,Date of first occurrence of N43 (hydrocele and spermatocele),icd10_n43_date,3 +132081-0.0,Date of first occurrence of N44 (torsion of testis),icd10_n44_date,3 +132083-0.0,Date of first occurrence of N45 (orchitis and epididymitis),icd10_n45_date,3 +132085-0.0,Date of first occurrence of N46 (male infertility),icd10_n46_date,3 +132087-0.0,"Date of first occurrence of N47 (redundant prepuce, phimosis and paraphimosis)",icd10_n47_date,3 +132089-0.0,Date of first occurrence of N48 (other disorders of penis),icd10_n48_date,3 +132091-0.0,"Date of first occurrence of N49 (inflammatory disorders of male genital organs, not elsewhere classified)",icd10_n49_date,3 +132093-0.0,Date of first occurrence of N50 (other disorders of male genital organs),icd10_n50_date,3 +132095-0.0,Date of first occurrence of N51 (disorders of male genital organs in diseases classified elsewhere),icd10_n51_date,3 +132097-0.0,Date of first occurrence of N60 (benign mammary dysplasia),icd10_n60_date,3 +132099-0.0,Date of first occurrence of N61 (inflammatory disorders of breast),icd10_n61_date,3 +132101-0.0,Date of first occurrence of N62 (hypertrophy of breast),icd10_n62_date,3 +132103-0.0,Date of first occurrence of N63 (unspecified lump in breast),icd10_n63_date,3 +132105-0.0,Date of first occurrence of N64 (other disorders of breast),icd10_n64_date,3 +132107-0.0,Date of first occurrence of N70 (salpingitis and oophoritis),icd10_n70_date,3 +132109-0.0,"Date of first occurrence of N71 (inflammatory disease of uterus, except cervix)",icd10_n71_date,3 +132111-0.0,Date of first occurrence of N72 (inflammatory disease of cervix uteri),icd10_n72_date,3 +132113-0.0,Date of first occurrence of N73 (other female pelvic inflammatory diseases),icd10_n73_date,3 +132115-0.0,Date of first occurrence of N74 (female pelvic inflammatory disorders in diseases classified elsewhere),icd10_n74_date,3 +132117-0.0,Date of first occurrence of N75 (diseases of bartholin's gland),icd10_n75_date,3 +132119-0.0,Date of first occurrence of N76 (other inflammation of vagina and vulva),icd10_n76_date,3 +132121-0.0,Date of first occurrence of N77 (vulvovaginal ulceration and inflammation in diseases classified elsewhere),icd10_n77_date,3 +132123-0.0,Date of first occurrence of N80 (endometriosis),icd10_n80_date,3 +132125-0.0,Date of first occurrence of N81 (female genital prolapse),icd10_n81_date,3 +132127-0.0,Date of first occurrence of N82 (fistulae involving female genital tract),icd10_n82_date,3 +132129-0.0,"Date of first occurrence of N83 (noninflammatory disorders of ovary, fallopian tube and broad ligament)",icd10_n83_date,3 +132131-0.0,Date of first occurrence of N84 (polyp of female genital tract),icd10_n84_date,3 +132133-0.0,"Date of first occurrence of N85 (other noninflammatory disorders of uterus, except cervix)",icd10_n85_date,3 +132135-0.0,Date of first occurrence of N86 (erosion and ectropion of cervix uteri),icd10_n86_date,3 +132137-0.0,Date of first occurrence of N87 (dysplasia of cervix uteri),icd10_n87_date,3 +132139-0.0,Date of first occurrence of N88 (other noninflammatory disorders of cervix uteri),icd10_n88_date,3 +132141-0.0,Date of first occurrence of N89 (other noninflammatory disorders of vagina),icd10_n89_date,3 +132143-0.0,Date of first occurrence of N90 (other noninflammatory disorders of vulva and perineum),icd10_n90_date,3 +132145-0.0,"Date of first occurrence of N91 (absent, scanty and rare menstruation)",icd10_n91_date,3 +132147-0.0,"Date of first occurrence of N92 (excessive, frequent and irregular menstruation)",icd10_n92_date,3 +132149-0.0,Date of first occurrence of N93 (other abnormal uterine and vaginal bleeding),icd10_n93_date,3 +132151-0.0,Date of first occurrence of N94 (pain and other conditions associated with female genital organs and menstrual cycle),icd10_n94_date,3 +132153-0.0,Date of first occurrence of N95 (menopausal and other perimenopausal disorders),icd10_n95_date,3 +132155-0.0,Date of first occurrence of N96 (habitual aborter),icd10_n96_date,3 +132157-0.0,Date of first occurrence of N97 (female infertility),icd10_n97_date,3 +132159-0.0,Date of first occurrence of N98 (complications associated with artificial fertilisation),icd10_n98_date,3 +132161-0.0,"Date of first occurrence of N99 (postprocedural disorders of genito-urinary system, not elsewhere classified)",icd10_n99_date,3 +132163-0.0,Date of first occurrence of O00 (ectopic pregnancy),icd10_o00_date,3 +132165-0.0,Date of first occurrence of O01 (hydatidiform mole),icd10_o01_date,3 +132167-0.0,Date of first occurrence of O02 (other abnormal products of conception),icd10_o02_date,3 +132169-0.0,Date of first occurrence of O03 (spontaneous abortion),icd10_o03_date,3 +132171-0.0,Date of first occurrence of O04 (medical abortion),icd10_o04_date,3 +132173-0.0,Date of first occurrence of O05 (other abortion),icd10_o05_date,3 +132175-0.0,Date of first occurrence of O06 (unspecified abortion),icd10_o06_date,3 +132177-0.0,Date of first occurrence of O07 (failed attempted abortion),icd10_o07_date,3 +132179-0.0,Date of first occurrence of O08 (complications following abortion and ectopic and molar pregnancy),icd10_o08_date,3 +132181-0.0,"Date of first occurrence of O10 (pre-existing hypertension complicating pregnancy, childbirth and the puerperium)",icd10_o10_date,3 +132183-0.0,Date of first occurrence of O11 (pre-existing hypertensive disorder with superimposed proteinuria),icd10_o11_date,3 +132185-0.0,Date of first occurrence of O12 (gestational [pregnancy-induced] oedema and proteinuria without hypertension),icd10_o12_date,3 +132187-0.0,Date of first occurrence of O13 (gestational [pregnancy-induced] hypertension without significant proteinuria),icd10_o13_date,3 +132189-0.0,Date of first occurrence of O14 (gestational [pregnancy-induced] hypertension with significant proteinuria),icd10_o14_date,3 +132191-0.0,Date of first occurrence of O15 (eclampsia),icd10_o15_date,3 +132193-0.0,Date of first occurrence of O16 (unspecified maternal hypertension),icd10_o16_date,3 +132195-0.0,Date of first occurrence of O20 (haemorrhage in early pregnancy),icd10_o20_date,3 +132197-0.0,Date of first occurrence of O21 (excessive vomiting in pregnancy),icd10_o21_date,3 +132199-0.0,Date of first occurrence of O22 (venous complications in pregnancy),icd10_o22_date,3 +132201-0.0,Date of first occurrence of O23 (infections of genito-urinary tract in pregnancy),icd10_o23_date,3 +132203-0.0,Date of first occurrence of O24 (diabetes mellitus in pregnancy),icd10_o24_date,3 +132205-0.0,Date of first occurrence of O25 (malnutrition in pregnancy),icd10_o25_date,3 +132207-0.0,Date of first occurrence of O26 (maternal care for other conditions predominantly related to pregnancy),icd10_o26_date,3 +132209-0.0,Date of first occurrence of O28 (abnormal findings on antenatal screening of mother),icd10_o28_date,3 +132211-0.0,Date of first occurrence of O29 (complications of anaesthesia during pregnancy),icd10_o29_date,3 +132213-0.0,Date of first occurrence of O30 (multiple gestation),icd10_o30_date,3 +132215-0.0,Date of first occurrence of O31 (complications specific to multiple gestation),icd10_o31_date,3 +132217-0.0,Date of first occurrence of O32 (maternal care for known or suspected malpresentation of foetus),icd10_o32_date,3 +132219-0.0,Date of first occurrence of O33 (maternal care for known or suspected disproportion),icd10_o33_date,3 +132221-0.0,Date of first occurrence of O34 (maternal care for known or suspected abnormality of pelvic organs),icd10_o34_date,3 +132223-0.0,Date of first occurrence of O35 (maternal care for known or suspected foetal abnormality and damage),icd10_o35_date,3 +132225-0.0,Date of first occurrence of O36 (maternal care for other known or suspected foetal problems),icd10_o36_date,3 +132227-0.0,Date of first occurrence of O40 (polyhydramnios),icd10_o40_date,3 +132229-0.0,Date of first occurrence of O41 (other disorders of amniotic fluid and membranes),icd10_o41_date,3 +132231-0.0,Date of first occurrence of O42 (premature rupture of membranes),icd10_o42_date,3 +132233-0.0,Date of first occurrence of O43 (placental disorders),icd10_o43_date,3 +132235-0.0,Date of first occurrence of O44 (placenta praevia),icd10_o44_date,3 +132237-0.0,Date of first occurrence of O45 (premature separation of placenta [abruptio placentae]),icd10_o45_date,3 +132239-0.0,"Date of first occurrence of O46 (antepartum haemorrhage, not elsewhere classified)",icd10_o46_date,3 +132241-0.0,Date of first occurrence of O47 (false labour),icd10_o47_date,3 +132243-0.0,Date of first occurrence of O48 (prolonged pregnancy),icd10_o48_date,3 +132245-0.0,Date of first occurrence of O60 (preterm delivery),icd10_o60_date,3 +132247-0.0,Date of first occurrence of O61 (failed induction of labour),icd10_o61_date,3 +132249-0.0,Date of first occurrence of O62 (abnormalities of forces of labour),icd10_o62_date,3 +132251-0.0,Date of first occurrence of O63 (long labour),icd10_o63_date,3 +132253-0.0,Date of first occurrence of O64 (obstructed labour due to malposition and malpresentation of foetus),icd10_o64_date,3 +132255-0.0,Date of first occurrence of O65 (obstructed labour due to maternal pelvic abnormality),icd10_o65_date,3 +132257-0.0,Date of first occurrence of O66 (other obstructed labour),icd10_o66_date,3 +132259-0.0,"Date of first occurrence of O67 (labour and delivery complicated by intrapartum haemorrhage, not elsewhere classified)",icd10_o67_date,3 +132261-0.0,Date of first occurrence of O68 (labour and delivery complicated by foetal stress [distress]),icd10_o68_date,3 +132263-0.0,Date of first occurrence of O69 (labour and delivery complicated by umbilical cord complications),icd10_o69_date,3 +132265-0.0,Date of first occurrence of O70 (perineal laceration during delivery),icd10_o70_date,3 +132267-0.0,Date of first occurrence of O71 (other obstetric trauma),icd10_o71_date,3 +132269-0.0,Date of first occurrence of O72 (postpartum haemorrhage),icd10_o72_date,3 +132271-0.0,"Date of first occurrence of O73 (retained placenta and membranes, without haemorrhage)",icd10_o73_date,3 +132273-0.0,Date of first occurrence of O74 (complications of anaesthesia during labour and delivery),icd10_o74_date,3 +132275-0.0,"Date of first occurrence of O75 (other complications of labour and delivery, not elsewhere classified)",icd10_o75_date,3 +132277-0.0,Date of first occurrence of O80 (single spontaneous delivery),icd10_o80_date,3 +132279-0.0,Date of first occurrence of O81 (single delivery by forceps and vacuum extractor),icd10_o81_date,3 +132281-0.0,Date of first occurrence of O82 (single delivery by caesarean section),icd10_o82_date,3 +132283-0.0,Date of first occurrence of O83 (other assisted single delivery),icd10_o83_date,3 +132285-0.0,Date of first occurrence of O84 (multiple delivery),icd10_o84_date,3 +132287-0.0,Date of first occurrence of O85 (puerperal sepsis),icd10_o85_date,3 +132289-0.0,Date of first occurrence of O86 (other puerperal infections),icd10_o86_date,3 +132291-0.0,Date of first occurrence of O87 (venous complications in the puerperium),icd10_o87_date,3 +132293-0.0,Date of first occurrence of O88 (obstetric embolism),icd10_o88_date,3 +132295-0.0,Date of first occurrence of O89 (complications of anaesthesia during the puerperium),icd10_o89_date,3 +132297-0.0,"Date of first occurrence of O90 (complications of the puerperium, not elsewhere classified)",icd10_o90_date,3 +132299-0.0,Date of first occurrence of O91 (infections of breast associated with childbirth),icd10_o91_date,3 +132301-0.0,Date of first occurrence of O92 (other disorders of breast and lactation associated with childbirth),icd10_o92_date,3 +132303-0.0,"Date of first occurrence of O94 (sequelae of complication of pregnancy, childbirth and the puerperium)",icd10_o94_date,3 +132307-0.0,Date of first occurrence of O96 (death from any obstetric cause occurring more than 42 days but less than one year after delivery),icd10_o96_date,3 +132311-0.0,"Date of first occurrence of O98 (maternal infectious and parasitic diseases classifiable elsewhere but complicating pregnancy, childbirth and the puerperium)",icd10_o98_date,3 +132313-0.0,"Date of first occurrence of O99 (other maternal diseases classifiable elsewhere but complicating pregnancy, childbirth and the puerperium)",icd10_o99_date,3 +132315-0.0,Date of first occurrence of P00 (foetus and newborn affected by maternal conditions that may be unrelated to present pregnancy),icd10_p00_date,3 +132319-0.0,"Date of first occurrence of P02 (foetus and newborn affected by complications of placenta, cord and membranes)",icd10_p02_date,3 +132321-0.0,Date of first occurrence of P03 (foetus and newborn affected by other complications of labour and delivery),icd10_p03_date,3 +132323-0.0,Date of first occurrence of P04 (foetus and newborn affected by noxious influences transmitted via placenta or breast milk),icd10_p04_date,3 +132325-0.0,Date of first occurrence of P05 (slow foetal growth and foetal malnutrition),icd10_p05_date,3 +132327-0.0,"Date of first occurrence of P07 (disorders related to short gestation and low birth weight, not elsewhere classified)",icd10_p07_date,3 +132329-0.0,Date of first occurrence of P08 (disorders related to long gestation and high birth weight),icd10_p08_date,3 +132331-0.0,Date of first occurrence of P10 (intracranial laceration and haemorrhage due to birth injury),icd10_p10_date,3 +132333-0.0,Date of first occurrence of P11 (other birth injuries to central nervous system),icd10_p11_date,3 +132335-0.0,Date of first occurrence of P12 (birth injury to scalp),icd10_p12_date,3 +132337-0.0,Date of first occurrence of P13 (birth injury to skeleton),icd10_p13_date,3 +132339-0.0,Date of first occurrence of P14 (birth injury to peripheral nervous system),icd10_p14_date,3 +132341-0.0,Date of first occurrence of P15 (other birth injuries),icd10_p15_date,3 +132343-0.0,Date of first occurrence of P20 (intra-uterine hypoxia),icd10_p20_date,3 +132345-0.0,Date of first occurrence of P21 (birth asphyxia),icd10_p21_date,3 +132347-0.0,Date of first occurrence of P22 (respiratory distress of newborn),icd10_p22_date,3 +132349-0.0,Date of first occurrence of P23 (congenital pneumonia),icd10_p23_date,3 +132351-0.0,Date of first occurrence of P24 (neonatal aspiration syndromes),icd10_p24_date,3 +132353-0.0,Date of first occurrence of P25 (interstitial emphysema and related conditions originating in the perinatal period),icd10_p25_date,3 +132355-0.0,Date of first occurrence of P26 (pulmonary haemorrhage originating in the perinatal period),icd10_p26_date,3 +132357-0.0,Date of first occurrence of P27 (chronic respiratory disease originating in the perinatal period),icd10_p27_date,3 +132359-0.0,Date of first occurrence of P28 (other respiratory conditions originating in the perinatal period),icd10_p28_date,3 +132361-0.0,Date of first occurrence of P29 (cardiovascular disorders originating in the perinatal period),icd10_p29_date,3 +132363-0.0,Date of first occurrence of P35 (congenital viral diseases),icd10_p35_date,3 +132365-0.0,Date of first occurrence of P36 (bacterial sepsis of newborn),icd10_p36_date,3 +132367-0.0,Date of first occurrence of P37 (other congenital infectious and parasitic diseases),icd10_p37_date,3 +132369-0.0,Date of first occurrence of P38 (omphalitis of newborn with or without mild haemorrhage),icd10_p38_date,3 +132371-0.0,Date of first occurrence of P39 (other infections specific to the perinatal period),icd10_p39_date,3 +132373-0.0,Date of first occurrence of P50 (foetal blood loss),icd10_p50_date,3 +132375-0.0,Date of first occurrence of P51 (umbilical haemorrhage of newborn),icd10_p51_date,3 +132377-0.0,Date of first occurrence of P52 (intracranial nontraumatic haemorrhage of foetus and newborn),icd10_p52_date,3 +132379-0.0,Date of first occurrence of P53 (haemorrhagic disease of foetus and newborn),icd10_p53_date,3 +132381-0.0,Date of first occurrence of P54 (other neonatal haemorrhages),icd10_p54_date,3 +132383-0.0,Date of first occurrence of P55 (haemolytic disease of foetus and newborn),icd10_p55_date,3 +132389-0.0,Date of first occurrence of P58 (neonatal jaundice due to other excessive haemolysis),icd10_p58_date,3 +132391-0.0,Date of first occurrence of P59 (neonatal jaundice from other and unspecified causes),icd10_p59_date,3 +132395-0.0,Date of first occurrence of P61 (other perinatal haematological disorders),icd10_p61_date,3 +132397-0.0,Date of first occurrence of P70 (transitory disorders of carbohydrate metabolism specific to foetus and newborn),icd10_p70_date,3 +132399-0.0,Date of first occurrence of P71 (transitory neonatal disorders of calcium and magnesium metabolism),icd10_p71_date,3 +132411-0.0,Date of first occurrence of P78 (other perinatal digestive system disorders),icd10_p78_date,3 +132417-0.0,Date of first occurrence of P83 (other conditions of integument specific to foetus and newborn),icd10_p83_date,3 +132421-0.0,Date of first occurrence of P91 (other disturbances of cerebral status of newborn),icd10_p91_date,3 +132423-0.0,Date of first occurrence of P92 (feeding problems of newborn),icd10_p92_date,3 +132427-0.0,Date of first occurrence of P94 (disorders of muscle tone of newborn),icd10_p94_date,3 +132429-0.0,Date of first occurrence of P95 (foetal death of unspecified cause),icd10_p95_date,3 +132431-0.0,Date of first occurrence of P96 (other conditions originating in the perinatal period),icd10_p96_date,3 +132433-0.0,Date of first occurrence of Q00 (anencephaly and similar malformations),icd10_q00_date,3 +132435-0.0,Date of first occurrence of Q01 (encephalocele),icd10_q01_date,3 +132437-0.0,Date of first occurrence of Q02 (microcephaly),icd10_q02_date,3 +132439-0.0,Date of first occurrence of Q03 (congenital hydrocephalus),icd10_q03_date,3 +132441-0.0,Date of first occurrence of Q04 (other congenital malformations of brain),icd10_q04_date,3 +132443-0.0,Date of first occurrence of Q05 (spina bifida),icd10_q05_date,3 +132445-0.0,Date of first occurrence of Q06 (other congenital malformations of spinal cord),icd10_q06_date,3 +132447-0.0,Date of first occurrence of Q07 (other congenital malformations of nervous system),icd10_q07_date,3 +132449-0.0,"Date of first occurrence of Q10 (congenital malformations of eyelid, lachrymal apparatus and orbit)",icd10_q10_date,3 +132451-0.0,"Date of first occurrence of Q11 (anophthalmos, microphthalmos and macrophthalmos)",icd10_q11_date,3 +132453-0.0,Date of first occurrence of Q12 (congenital lens malformations),icd10_q12_date,3 +132455-0.0,Date of first occurrence of Q13 (congenital malformations of anterior segment of eye),icd10_q13_date,3 +132457-0.0,Date of first occurrence of Q14 (congenital malformations of posterior segment of eye),icd10_q14_date,3 +132459-0.0,Date of first occurrence of Q15 (other congenital malformations of eye),icd10_q15_date,3 +132461-0.0,Date of first occurrence of Q16 (congenital malformations of ear causing impairment of hearing),icd10_q16_date,3 +132463-0.0,Date of first occurrence of Q17 (other congenital malformations of ear),icd10_q17_date,3 +132465-0.0,Date of first occurrence of Q18 (other congenital malformations of face and neck),icd10_q18_date,3 +132467-0.0,Date of first occurrence of Q20 (congenital malformations of cardiac chambers and connexions),icd10_q20_date,3 +132469-0.0,Date of first occurrence of Q21 (congenital malformations of cardiac septa),icd10_q21_date,3 +132471-0.0,Date of first occurrence of Q22 (congenital malformations of pulmonary and tricuspid valves),icd10_q22_date,3 +132473-0.0,Date of first occurrence of Q23 (congenital malformations of aortic and mitral valves),icd10_q23_date,3 +132475-0.0,Date of first occurrence of Q24 (other congenital malformations of heart),icd10_q24_date,3 +132477-0.0,Date of first occurrence of Q25 (congenital malformations of great arteries),icd10_q25_date,3 +132479-0.0,Date of first occurrence of Q26 (congenital malformations of great veins),icd10_q26_date,3 +132481-0.0,Date of first occurrence of Q27 (other congenital malformations of peripheral vascular system),icd10_q27_date,3 +132483-0.0,Date of first occurrence of Q28 (other congenital malformations of circulatory system),icd10_q28_date,3 +132485-0.0,Date of first occurrence of Q30 (congenital malformations of nose),icd10_q30_date,3 +132487-0.0,Date of first occurrence of Q31 (congenital malformations of larynx),icd10_q31_date,3 +132489-0.0,Date of first occurrence of Q32 (congenital malformations of trachea and bronchus),icd10_q32_date,3 +132491-0.0,Date of first occurrence of Q33 (congenital malformations of lung),icd10_q33_date,3 +132493-0.0,Date of first occurrence of Q34 (other congenital malformations of respiratory system),icd10_q34_date,3 +132495-0.0,Date of first occurrence of Q35 (cleft palate),icd10_q35_date,3 +132497-0.0,Date of first occurrence of Q36 (cleft lip),icd10_q36_date,3 +132499-0.0,Date of first occurrence of Q37 (cleft palate with cleft lip),icd10_q37_date,3 +132501-0.0,"Date of first occurrence of Q38 (other congenital malformations of tongue, mouth and pharynx)",icd10_q38_date,3 +132503-0.0,Date of first occurrence of Q39 (congenital malformations of oesophagus),icd10_q39_date,3 +132505-0.0,Date of first occurrence of Q40 (other congenital malformations of upper alimentary tract),icd10_q40_date,3 +132507-0.0,"Date of first occurrence of Q41 (congenital absence, atresia and stenosis of small intestine)",icd10_q41_date,3 +132509-0.0,"Date of first occurrence of Q42 (congenital absence, atresia and stenosis of large intestine)",icd10_q42_date,3 +132511-0.0,Date of first occurrence of Q43 (other congenital malformations of intestine),icd10_q43_date,3 +132513-0.0,"Date of first occurrence of Q44 (congenital malformations of gallbladder, bile ducts and liver)",icd10_q44_date,3 +132515-0.0,Date of first occurrence of Q45 (other congenital malformations of digestive system),icd10_q45_date,3 +132517-0.0,"Date of first occurrence of Q50 (congenital malformations of ovaries, fallopian tubes and broad ligaments)",icd10_q50_date,3 +132519-0.0,Date of first occurrence of Q51 (congenital malformations of uterus and cervix),icd10_q51_date,3 +132521-0.0,Date of first occurrence of Q52 (other congenital malformations of female genitalia),icd10_q52_date,3 +132523-0.0,Date of first occurrence of Q53 (undescended testicle),icd10_q53_date,3 +132525-0.0,Date of first occurrence of Q54 (hypospadias),icd10_q54_date,3 +132527-0.0,Date of first occurrence of Q55 (other congenital malformations of male genital organs),icd10_q55_date,3 +132529-0.0,Date of first occurrence of Q56 (indeterminate sex and pseudohermaphroditism),icd10_q56_date,3 +132531-0.0,Date of first occurrence of Q60 (renal agenesis and other reduction defects of kidney),icd10_q60_date,3 +132533-0.0,Date of first occurrence of Q61 (cystic kidney disease),icd10_q61_date,3 +132535-0.0,Date of first occurrence of Q62 (congenital obstructive defects of renal pelvis and congenital malformations of ureter),icd10_q62_date,3 +132537-0.0,Date of first occurrence of Q63 (other congenital malformations of kidney),icd10_q63_date,3 +132539-0.0,Date of first occurrence of Q64 (other congenital malformations of urinary system),icd10_q64_date,3 +132541-0.0,Date of first occurrence of Q65 (congenital deformities of hip),icd10_q65_date,3 +132543-0.0,Date of first occurrence of Q66 (congenital deformities of feet),icd10_q66_date,3 +132545-0.0,"Date of first occurrence of Q67 (congenital musculoskeletal deformities of head, face, spine and chest)",icd10_q67_date,3 +132547-0.0,Date of first occurrence of Q68 (other congenital musculoskeletal deformities),icd10_q68_date,3 +132549-0.0,Date of first occurrence of Q69 (polydactyly),icd10_q69_date,3 +132551-0.0,Date of first occurrence of Q70 (syndactyly),icd10_q70_date,3 +132553-0.0,Date of first occurrence of Q71 (reduction defects of upper limb),icd10_q71_date,3 +132555-0.0,Date of first occurrence of Q72 (reduction defects of lower limb),icd10_q72_date,3 +132557-0.0,Date of first occurrence of Q73 (reduction defects of unspecified limb),icd10_q73_date,3 +132559-0.0,Date of first occurrence of Q74 (other congenital malformations of limb(s)),icd10_q74_date,3 +132561-0.0,Date of first occurrence of Q75 (other congenital malformations of skull and face bones),icd10_q75_date,3 +132563-0.0,Date of first occurrence of Q76 (congenital malformations of spine and bony thorax),icd10_q76_date,3 +132565-0.0,Date of first occurrence of Q77 (osteochondrodysplasia with defects of growth of tubular bones and spine),icd10_q77_date,3 +132567-0.0,Date of first occurrence of Q78 (other osteochondrodysplasias),icd10_q78_date,3 +132569-0.0,"Date of first occurrence of Q79 (congenital malformations of musculoskeletal system, not elsewhere classified)",icd10_q79_date,3 +132571-0.0,Date of first occurrence of Q80 (congenital ichthyosis),icd10_q80_date,3 +132573-0.0,Date of first occurrence of Q81 (epidermolysis bullosa),icd10_q81_date,3 +132575-0.0,Date of first occurrence of Q82 (other congenital malformations of skin),icd10_q82_date,3 +132577-0.0,Date of first occurrence of Q83 (congenital malformations of breast),icd10_q83_date,3 +132579-0.0,Date of first occurrence of Q84 (other congenital malformations of integument),icd10_q84_date,3 +132581-0.0,"Date of first occurrence of Q85 (phakomatoses, not elsewhere classified)",icd10_q85_date,3 +132583-0.0,"Date of first occurrence of Q86 (congenital malformation syndromes due to known exogenous causes, not elsewhere classified)",icd10_q86_date,3 +132585-0.0,Date of first occurrence of Q87 (other specified congenital malformation syndromes affecting multiple systems),icd10_q87_date,3 +132587-0.0,"Date of first occurrence of Q89 (other congenital malformations, not elsewhere classified)",icd10_q89_date,3 +132589-0.0,Date of first occurrence of Q90 (down's syndrome),icd10_q90_date,3 +132591-0.0,Date of first occurrence of Q91 (edwards' syndrome and patau's syndrome),icd10_q91_date,3 +132593-0.0,"Date of first occurrence of Q92 (other trisomies and partial trisomies of the autosomes, not elsewhere classified)",icd10_q92_date,3 +132595-0.0,"Date of first occurrence of Q93 (monosomies and deletions from the autosomes, not elsewhere classified)",icd10_q93_date,3 +132597-0.0,"Date of first occurrence of Q95 (balanced rearrangements and structural markers, not elsewhere classified)",icd10_q95_date,3 +132599-0.0,Date of first occurrence of Q96 (turner's syndrome),icd10_q96_date,3 +132601-0.0,"Date of first occurrence of Q97 (other sex chromosome abnormalities, female phenotype, not elsewhere classified)",icd10_q97_date,3 +132603-0.0,"Date of first occurrence of Q98 (other sex chromosome abnormalities, male phenotype, not elsewhere classified)",icd10_q98_date,3 +132605-0.0,"Date of first occurrence of Q99 (other chromosome abnormalities, not elsewhere classified)",icd10_q99_date,3 +40005-0.0,"Date of cancer diagnosis, ICD10 (array 0)",cancer_date_icd10_0,3 +40005-1.0,"Date of cancer diagnosis, ICD10 (array 1)",cancer_date_icd10_1,3 +40005-2.0,"Date of cancer diagnosis, ICD10 (array 2)",cancer_date_icd10_2,3 +40005-3.0,"Date of cancer diagnosis, ICD10 (array 3)",cancer_date_icd10_3,3 +40005-4.0,"Date of cancer diagnosis, ICD10 (array 4)",cancer_date_icd10_4,3 +40005-5.0,"Date of cancer diagnosis, ICD10 (array 5)",cancer_date_icd10_5,3 +40005-6.0,"Date of cancer diagnosis, ICD10 (array 6)",cancer_date_icd10_6,3 +40005-7.0,"Date of cancer diagnosis, ICD10 (array 7)",cancer_date_icd10_7,3 +40005-8.0,"Date of cancer diagnosis, ICD10 (array 8)",cancer_date_icd10_8,3 +40005-9.0,"Date of cancer diagnosis, ICD10 (array 9)",cancer_date_icd10_9,3 +40005-10.0,"Date of cancer diagnosis, ICD10 (array 10)",cancer_date_icd10_10,3 +40005-11.0,"Date of cancer diagnosis, ICD10 (array 11)",cancer_date_icd10_11,3 +40005-12.0,"Date of cancer diagnosis, ICD10 (array 12)",cancer_date_icd10_12,3 +40005-13.0,"Date of cancer diagnosis, ICD10 (array 13)",cancer_date_icd10_13,3 +40005-14.0,"Date of cancer diagnosis, ICD10 (array 14)",cancer_date_icd10_14,3 +40005-15.0,"Date of cancer diagnosis, ICD10 (array 15)",cancer_date_icd10_15,3 +40005-16.0,"Date of cancer diagnosis, ICD10 (array 16)",cancer_date_icd10_16,3 diff --git a/future_risk.py b/future_risk.py new file mode 100644 index 0000000..8480b1a --- /dev/null +++ b/future_risk.py @@ -0,0 +1,115 @@ +from __future__ import annotations + +from collections.abc import Sequence + +import torch +import torch.nn.functional as F + + +def death_token(vocab_size: int) -> int: + if int(vocab_size) <= 0: + raise ValueError(f"vocab_size must be positive, got {vocab_size}") + return int(vocab_size) - 1 + + +def probabilities_from_logits( + logits: torch.Tensor, + tau_years: float | torch.Tensor, + *, + dist_mode: str = "exponential", + rho: torch.Tensor | None = None, + death_rho: torch.Tensor | None = None, + eps: float = 1e-8, +) -> torch.Tensor: + """ + Convert all-future logits to tau-year event probabilities. + + Death is always treated as token vocab_size - 1. For dist_mode="mixed", + non-death tokens use exponential hazards and death uses death_rho. + """ + if logits.ndim != 2: + raise ValueError(f"logits must have shape (N, V), got {tuple(logits.shape)}") + if float(torch.as_tensor(tau_years).detach().min().cpu()) < 0: + raise ValueError("tau_years must be non-negative") + + mode = str(dist_mode).lower() + if mode not in {"exponential", "weibull", "mixed"}: + raise ValueError("dist_mode must be one of: exponential, weibull, mixed") + + rate = F.softplus(logits) + float(eps) + tau = torch.as_tensor(tau_years, dtype=rate.dtype, device=rate.device) + if tau.ndim == 0: + tau = tau.expand(logits.shape[0]) + if tau.ndim != 1 or tau.shape[0] != logits.shape[0]: + raise ValueError( + "tau_years must be a scalar or a 1D tensor with length N, got " + f"{tuple(tau.shape)} for N={logits.shape[0]}" + ) + + if mode == "exponential": + exposure = tau[:, None].expand_as(rate) + elif mode == "weibull": + if rho is None or rho.shape != logits.shape: + raise ValueError("rho must have the same shape as logits for dist_mode='weibull'") + exposure = torch.pow(tau[:, None].clamp_min(float(eps)), rho.to(rate.dtype)) + else: + exposure = tau[:, None].expand_as(rate).clone() + if death_rho is None: + raise ValueError("death_rho is required for dist_mode='mixed'") + death_idx = death_token(logits.shape[1]) + death_shape = tuple(death_rho.shape) + death_rho = death_rho.to(device=rate.device, dtype=rate.dtype) + if death_rho.ndim == 2 and death_rho.shape[1] == 1: + death_rho = death_rho.squeeze(1) + if death_rho.ndim != 1 or death_rho.shape[0] != logits.shape[0]: + raise ValueError( + "death_rho must have shape (N,) or (N, 1), got " + f"{death_shape} for N={logits.shape[0]}" + ) + exposure[:, death_idx] = torch.pow(tau.clamp_min(float(eps)), death_rho) + + return -torch.expm1(-rate * exposure) + + +def death_risk_from_probabilities(probabilities: torch.Tensor) -> torch.Tensor: + """Return p_death(t, tau), with death fixed to token vocab_size - 1.""" + if probabilities.ndim != 2: + raise ValueError( + f"probabilities must have shape (N, V), got {tuple(probabilities.shape)}" + ) + return probabilities[:, death_token(probabilities.shape[1])] + + +def new_disease_risk_from_probabilities( + probabilities: torch.Tensor, + occurred: torch.Tensor, + disease_ids: Sequence[int], +) -> torch.Tensor: + """ + Compute P(at least one selected disease newly occurs within tau years). + + Already occurred diseases are masked out. Death is not included here and + should be reported separately with death_risk_from_probabilities. + """ + if probabilities.ndim != 2 or occurred.shape != probabilities.shape: + raise ValueError( + "probabilities and occurred must both have shape (N, V), got " + f"{tuple(probabilities.shape)} and {tuple(occurred.shape)}" + ) + if not disease_ids: + return probabilities.new_zeros(probabilities.shape[0]) + + death_idx = death_token(probabilities.shape[1]) + ids = [ + idx + for idx in dict.fromkeys(int(x) for x in disease_ids) + if 0 <= idx < probabilities.shape[1] and idx != death_idx + ] + if not ids: + return probabilities.new_zeros(probabilities.shape[0]) + + idx_tensor = torch.as_tensor(ids, dtype=torch.long, device=probabilities.device) + p = probabilities[:, idx_tensor].clamp(0.0, 1.0 - 1e-7) + new_mask = ~occurred[:, idx_tensor].to(dtype=torch.bool) + log_no_new = torch.log1p(-p) * new_mask.to(dtype=p.dtype) + return -torch.expm1(log_no_new.sum(dim=1)) diff --git a/labels.csv b/labels.csv new file mode 100644 index 0000000..7aa58cb --- /dev/null +++ b/labels.csv @@ -0,0 +1,1256 @@ +A00 (cholera) +A01 (typhoid and paratyphoid fevers) +A02 (other salmonella infections) +A03 (shigellosis) +A04 (other bacterial intestinal infections) +A05 (other bacterial foodborne intoxications) +A06 (amoebiasis) +A07 (other protozoal intestinal diseases) +A08 (viral and other specified intestinal infections) +A09 (diarrhoea and gastro-enteritis of presumed infectious origin) +A15 (respiratory tuberculosis, bacteriologically and histologically confirmed) +A16 (respiratory tuberculosis, not confirmed bacteriologically or histologically) +A17 (tuberculosis of nervous system) +A18 (tuberculosis of other organs) +A19 (miliary tuberculosis) +A20 (plague) +A22 (anthrax) +A23 (brucellosis) +A24 (glanders and melioidosis) +A25 (rat-bite fevers) +A26 (erysipeloid) +A27 (leptospirosis) +A28 (other zoonotic bacterial diseases, not elsewhere classified) +A30 (leprosy [hansen's disease]) +A31 (infection due to other mycobacteria) +A32 (listeriosis) +A33 (tetanus neonatorum) +A35 (other tetanus) +A36 (diphtheria) +A37 (whooping cough) +A38 (scarlet fever) +A39 (meningococcal infection) +A40 (streptococcal septicaemia) +A41 (other septicaemia) +A42 (actinomycosis) +A43 (nocardiosis) +A44 (bartonellosis) +A46 (erysipelas) +A48 (other bacterial diseases, not elsewhere classified) +A49 (bacterial infection of unspecified site) +A50 (congenital syphilis) +A51 (early syphilis) +A52 (late syphilis) +A53 (other and unspecified syphilis) +A54 (gonococcal infection) +A55 (chlamydial lymphogranuloma (venereum)) +A56 (other sexually transmitted chlamydial diseases) +A58 (granuloma inguinale) +A59 (trichomoniasis) +A60 (anogenital herpesviral [herpes simplex] infections) +A63 (other predominantly sexually transmitted diseases, not elsewhere classified) +A64 (unspecified sexually transmitted disease) +A66 (yaws) +A67 (pinta [carate]) +A68 (relapsing fevers) +A69 (other spirochaetal infections) +A70 (chlamydia psittaci infection) +A71 (trachoma) +A74 (other diseases caused by chlamydiae) +A75 (typhus fever) +A77 (spotted fever [tick-borne rickettsioses]) +A78 (q fever) +A79 (other rickettsioses) +A80 (acute poliomyelitis) +A81 (atypical virus infections of central nervous system) +A82 (rabies) +A83 (mosquito-borne viral encephalitis) +A84 (tick-borne viral encephalitis) +A85 (other viral encephalitis, not elsewhere classified) +A86 (unspecified viral encephalitis) +A87 (viral meningitis) +A88 (other viral infections of central nervous system, not elsewhere classified) +A89 (unspecified viral infection of central nervous system) +A90 (dengue fever [classical dengue]) +A91 (dengue haemorrhagic fever) +A92 (other mosquito-borne viral fevers) +A93 (other arthropod-borne viral fevers, not elsewhere classified) +A94 (unspecified arthropod-borne viral fever) +A95 (yellow fever) +A97 (dengue) +A98 (other viral haemorrhagic fevers, not elsewhere classified) +B00 (herpesviral [herpes simplex] infections) +B01 (varicella [chickenpox]) +B02 (zoster [herpes zoster]) +B03 (smallpox) +B05 (measles) +B06 (rubella [german measles]) +B07 (viral warts) +B08 (other viral infections characterised by skin and mucous membrane lesions, not elsewhere classified) +B09 (unspecified viral infection characterised by skin and mucous membrane lesions) +B15 (acute hepatitis a) +B16 (acute hepatitis b) +B17 (other acute viral hepatitis) +B18 (chronic viral hepatitis) +B19 (unspecified viral hepatitis) +B20 (human immunodeficiency virus [hiv] disease resulting in infectious and parasitic diseases) +B21 (human immunodeficiency virus [hiv] disease resulting in malignant neoplasms) +B22 (human immunodeficiency virus [hiv] disease resulting in other specified diseases) +B23 (human immunodeficiency virus [hiv] disease resulting in other conditions) +B24 (unspecified human immunodeficiency virus [hiv] disease) +B25 (cytomegaloviral disease) +B26 (mumps) +B27 (infectious mononucleosis) +B30 (viral conjunctivitis) +B33 (other viral diseases, not elsewhere classified) +B34 (viral infection of unspecified site) +B35 (dermatophytosis) +B36 (other superficial mycoses) +B37 (candidiasis) +B38 (coccidioidomycosis) +B39 (histoplasmosis) +B40 (blastomycosis) +B42 (sporotrichosis) +B43 (chromomycosis and phaeomycotic abscess) +B44 (aspergillosis) +B45 (cryptococcosis) +B46 (zygomycosis) +B47 (mycetoma) +B48 (other mycoses, not elsewhere classified) +B49 (unspecified mycosis) +B50 (plasmodium falciparum malaria) +B51 (plasmodium vivax malaria) +B52 (plasmodium malariae malaria) +B53 (other parasitologically confirmed malaria) +B54 (unspecified malaria) +B55 (leishmaniasis) +B57 (chagas' disease) +B58 (toxoplasmosis) +B59 (pneumocystosis) +B60 (other protozoal diseases, not elsewhere classified) +B65 (schistosomiasis [bilharziasis]) +B66 (other fluke infections) +B67 (echinococcosis) +B68 (taeniasis) +B69 (cysticercosis) +B71 (other cestode infections) +B73 (onchocerciasis) +B74 (filariasis) +B75 (trichinellosis) +B76 (hookworm diseases) +B77 (ascariasis) +B78 (strongyloidiasis) +B79 (trichuriasis) +B80 (enterobiasis) +B81 (other intestinal helminthiases, not elsewhere classified) +B82 (unspecified intestinal parasitism) +B83 (other helminthiases) +B85 (pediculosis and phthiriasis) +B86 (scabies) +B87 (myiasis) +B88 (other infestations) +B89 (unspecified parasitic disease) +B90 (sequelae of tuberculosis) +B91 (sequelae of poliomyelitis) +B94 (sequelae of other and unspecified infectious and parasitic diseases) +B95 (streptococcus and staphylococcus as the cause of diseases classified to other chapters) +B96 (other bacterial agents as the cause of diseases classified to other chapters) +B97 (viral agents as the cause of diseases classified to other chapters) +B98 (other specified infectious agents as the cause of diseases classified to other chapters) +B99 (other and unspecified infectious diseases) +D50 (iron deficiency anaemia) +D51 (vitamin b12 deficiency anaemia) +D52 (folate deficiency anaemia) +D53 (other nutritional anaemias) +D55 (anaemia due to enzyme disorders) +D56 (thalassaemia) +D57 (sickle-cell disorders) +D58 (other hereditary haemolytic anaemias) +D59 (acquired haemolytic anaemia) +D60 (acquired pure red cell aplasia [erythroblastopenia]) +D61 (other aplastic anaemias) +D62 (acute posthaemorrhagic anaemia) +D63 (anaemia in chronic diseases classified elsewhere) +D64 (other anaemias) +D65 (disseminated intravascular coagulation [defibrination syndrome]) +D66 (hereditary factor viii deficiency) +D67 (hereditary factor ix deficiency) +D68 (other coagulation defects) +D69 (purpura and other haemorrhagic conditions) +D70 (agranulocytosis) +D71 (functional disorders of polymorphonuclear neutrophils) +D72 (other disorders of white blood cells) +D73 (diseases of spleen) +D74 (methaemoglobinaemia) +D75 (other diseases of blood and blood-forming organs) +D76 (certain diseases involving lymphoreticular tissue and reticulohistiocytic system) +D77 (other disorders of blood and blood-forming organs in diseases classified elsewhere) +D80 (immunodeficiency with predominantly antibody defects) +D81 (combined immunodeficiencies) +D82 (immunodeficiency associated with other major defects) +D83 (common variable immunodeficiency) +D84 (other immunodeficiencies) +D86 (sarcoidosis) +D89 (other disorders involving the immune mechanism, not elsewhere classified) +E01 (iodine-deficiency-related thyroid disorders and allied conditions) +E02 (subclinical iodine-deficiency hypothyroidism) +E03 (other hypothyroidism) +E04 (other non-toxic goitre) +E05 (thyrotoxicosis [hyperthyroidism]) +E06 (thyroiditis) +E07 (other disorders of thyroid) +E10 (insulin-dependent diabetes mellitus) +E11 (non-insulin-dependent diabetes mellitus) +E12 (malnutrition-related diabetes mellitus) +E13 (other specified diabetes mellitus) +E14 (unspecified diabetes mellitus) +E15 (nondiabetic hypoglycaemic coma) +E16 (other disorders of pancreatic internal secretion) +E20 (hypoparathyroidism) +E21 (hyperparathyroidism and other disorders of parathyroid gland) +E22 (hyperfunction of pituitary gland) +E23 (hypofunction and other disorders of pituitary gland) +E24 (cushing's syndrome) +E25 (adrenogenital disorders) +E26 (hyperaldosteronism) +E27 (other disorders of adrenal gland) +E28 (ovarian dysfunction) +E29 (testicular dysfunction) +E30 (disorders of puberty, not elsewhere classified) +E31 (polyglandular dysfunction) +E32 (diseases of thymus) +E34 (other endocrine disorders) +E35 (disorders of endocrine glands in diseases classified elsewhere) +E41 (nutritional marasmus) +E43 (unspecified severe protein-energy malnutrition) +E44 (protein-energy malnutrition of moderate and mild degree) +E45 (retarded development following protein-energy malnutrition) +E46 (unspecified protein-energy malnutrition) +E50 (vitamin a deficiency) +E51 (thiamine deficiency) +E52 (niacin deficiency [pellagra]) +E53 (deficiency of other b group vitamins) +E54 (ascorbic acid deficiency) +E55 (vitamin d deficiency) +E56 (other vitamin deficiencies) +E58 (dietary calcium deficiency) +E59 (dietary selenium deficiency) +E60 (dietary zinc deficiency) +E61 (deficiency of other nutrient elements) +E63 (other nutritional deficiencies) +E64 (sequelae of malnutrition and other nutritional deficiencies) +E65 (localised adiposity) +E66 (obesity) +E67 (other hyperalimentation) +E68 (sequelae of hyperalimentation) +E70 (disorders of aromatic amino-acid metabolism) +E71 (disorders of branched-chain amino-acid metabolism and fatty-acid metabolism) +E72 (other disorders of amino-acid metabolism) +E73 (lactose intolerance) +E74 (other disorders of carbohydrate metabolism) +E75 (disorders of sphingolipid metabolism and other lipid storage disorders) +E76 (disorders of glycosaminoglycan metabolism) +E77 (disorders of glycoprotein metabolism) +E78 (disorders of lipoprotein metabolism and other lipidaemias) +E79 (disorders of purine and pyrimidine metabolism) +E80 (disorders of porphyrin and bilirubin metabolism) +E83 (disorders of mineral metabolism) +E84 (cystic fibrosis) +E85 (amyloidosis) +E86 (volume depletion) +E87 (other disorders of fluid, electrolyte and acid-base balance) +E88 (other metabolic disorders) +E89 (postprocedural endocrine and metabolic disorders, not elsewhere classified) +F00 (dementia in alzheimer's disease) +F01 (vascular dementia) +F02 (dementia in other diseases classified elsewhere) +F03 (unspecified dementia) +F04 (organic amnesic syndrome, not induced by alcohol and other psychoactive substances) +F05 (delirium, not induced by alcohol and other psychoactive substances) +F06 (other mental disorders due to brain damage and dysfunction and to physical disease) +F07 (personality and behavioural disorders due to brain disease, damage and dysfunction) +F09 (unspecified organic or symptomatic mental disorder) +F10 (mental and behavioural disorders due to use of alcohol) +F11 (mental and behavioural disorders due to use of opioids) +F12 (mental and behavioural disorders due to use of cannabinoids) +F13 (mental and behavioural disorders due to use of sedatives or hypnotics) +F14 (mental and behavioural disorders due to use of cocaine) +F15 (mental and behavioural disorders due to use of other stimulants, including caffeine) +F16 (mental and behavioural disorders due to use of hallucinogens) +F17 (mental and behavioural disorders due to use of tobacco) +F18 (mental and behavioural disorders due to use of volatile solvents) +F19 (mental and behavioural disorders due to multiple drug use and use of other psychoactive substances) +F20 (schizophrenia) +F21 (schizotypal disorder) +F22 (persistent delusional disorders) +F23 (acute and transient psychotic disorders) +F24 (induced delusional disorder) +F25 (schizoaffective disorders) +F28 (other nonorganic psychotic disorders) +F29 (unspecified nonorganic psychosis) +F30 (manic episode) +F31 (bipolar affective disorder) +F32 (depressive episode) +F33 (recurrent depressive disorder) +F34 (persistent mood [affective] disorders) +F38 (other mood [affective] disorders) +F39 (unspecified mood [affective] disorder) +F40 (phobic anxiety disorders) +F41 (other anxiety disorders) +F42 (obsessive-compulsive disorder) +F43 (reaction to severe stress, and adjustment disorders) +F44 (dissociative [conversion] disorders) +F45 (somatoform disorders) +F48 (other neurotic disorders) +F50 (eating disorders) +F51 (nonorganic sleep disorders) +F52 (sexual dysfunction, not caused by organic disorder or disease) +F53 (mental and behavioural disorders associated with the puerperium, not elsewhere classified) +F54 (psychological and behavioural factors associated with disorders or diseases classified elsewhere) +F55 (abuse of non-dependence-producing substances) +F59 (unspecified behavioural syndromes associated with physiological disturbances and physical factors) +F60 (specific personality disorders) +F61 (mixed and other personality disorders) +F62 (enduring personality changes, not attributable to brain damage and disease) +F63 (habit and impulse disorders) +F64 (gender identity disorders) +F65 (disorders of sexual preference) +F66 (psychological and behavioural disorders associated with sexual development and orientation) +F68 (other disorders of adult personality and behaviour) +F69 (unspecified disorder of adult personality and behaviour) +F70 (mild mental retardation) +F71 (moderate mental retardation) +F72 (severe mental retardation) +F78 (other mental retardation) +F79 (unspecified mental retardation) +F80 (specific developmental disorders of speech and language) +F81 (specific developmental disorders of scholastic skills) +F82 (specific developmental disorder of motor function) +F83 (mixed specific developmental disorders) +F84 (pervasive developmental disorders) +F88 (other disorders of psychological development) +F89 (unspecified disorder of psychological development) +F90 (hyperkinetic disorders) +F91 (conduct disorders) +F92 (mixed disorders of conduct and emotions) +F93 (emotional disorders with onset specific to childhood) +F94 (disorders of social functioning with onset specific to childhood and adolescence) +F95 (tic disorders) +F98 (other behavioural and emotional disorders with onset usually occurring in childhood and adolescence) +F99 (mental disorder, not otherwise specified) +G00 (bacterial meningitis, not elsewhere classified) +G01 (meningitis in bacterial diseases classified elsewhere) +G02 (meningitis in other infectious and parasitic diseases classified elsewhere) +G03 (meningitis due to other and unspecified causes) +G04 (encephalitis, myelitis and encephalomyelitis) +G05 (encephalitis, myelitis and encephalomyelitis in diseases classified elsewhere) +G06 (intracranial and intraspinal abscess and granuloma) +G07 (intracranial and intraspinal abscess and granuloma in diseases classified elsewhere) +G08 (intracranial and intraspinal phlebitis and thrombophlebitis) +G09 (sequelae of inflammatory diseases of central nervous system) +G10 (huntington's disease) +G11 (hereditary ataxia) +G12 (spinal muscular atrophy and related syndromes) +G13 (systemic atrophies primarily affecting central nervous system in diseases classified elsewhere) +G14 (postpolio syndrome) +G20 (parkinson's disease) +G21 (secondary parkinsonism) +G22 (parkinsonism in diseases classified elsewhere) +G23 (other degenerative diseases of basal ganglia) +G24 (dystonia) +G25 (other extrapyramidal and movement disorders) +G30 (alzheimer's disease) +G31 (other degenerative diseases of nervous system, not elsewhere classified) +G32 (other degenerative disorders of nervous system in diseases classified elsewhere) +G35 (multiple sclerosis) +G36 (other acute disseminated demyelination) +G37 (other demyelinating diseases of central nervous system) +G40 (epilepsy) +G41 (status epilepticus) +G43 (migraine) +G44 (other headache syndromes) +G45 (transient cerebral ischaemic attacks and related syndromes) +G46 (vascular syndromes of brain in cerebrovascular diseases) +G47 (sleep disorders) +G50 (disorders of trigeminal nerve) +G51 (facial nerve disorders) +G52 (disorders of other cranial nerves) +G53 (cranial nerve disorders in diseases classified elsewhere) +G54 (nerve root and plexus disorders) +G55 (nerve root and plexus compressions in diseases classified elsewhere) +G56 (mononeuropathies of upper limb) +G57 (mononeuropathies of lower limb) +G58 (other mononeuropathies) +G59 (mononeuropathy in diseases classified elsewhere) +G60 (hereditary and idiopathic neuropathy) +G61 (inflammatory polyneuropathy) +G62 (other polyneuropathies) +G63 (polyneuropathy in diseases classified elsewhere) +G64 (other disorders of peripheral nervous system) +G70 (myasthenia gravis and other myoneural disorders) +G71 (primary disorders of muscles) +G72 (other myopathies) +G73 (disorders of myoneural junction and muscle in diseases classified elsewhere) +G80 (infantile cerebral palsy) +G81 (hemiplegia) +G82 (paraplegia and tetraplegia) +G83 (other paralytic syndromes) +G90 (disorders of autonomic nervous system) +G91 (hydrocephalus) +G92 (toxic encephalopathy) +G93 (other disorders of brain) +G94 (other disorders of brain in diseases classified elsewhere) +G95 (other diseases of spinal cord) +G96 (other disorders of central nervous system) +G97 (postprocedural disorders of nervous system, not elsewhere classified) +G98 (other disorders of nervous system, not elsewhere classified) +G99 (other disorders of nervous system in diseases classified elsewhere) +H00 (hordeolum and chalazion) +H01 (other inflammation of eyelid) +H02 (other disorders of eyelid) +H03 (disorders of eyelid in diseases classified elsewhere) +H04 (disorders of lachrymal system) +H05 (disorders of orbit) +H06 (disorders of lachrymal system and orbit in diseases classified elsewhere) +H10 (conjunctivitis) +H11 (other disorders of conjunctiva) +H13 (disorders of conjunctiva in diseases classified elsewhere) +H15 (disorders of sclera) +H16 (keratitis) +H17 (corneal scars and opacities) +H18 (other disorders of cornea) +H19 (disorders of sclera and cornea in diseases classified elsewhere) +H20 (iridocyclitis) +H21 (other disorders of iris and ciliary body) +H22 (disorders of iris and ciliary body in diseases classified elsewhere) +H25 (senile cataract) +H26 (other cataract) +H27 (other disorders of lens) +H28 (cataract and other disorders of lens in diseases classified elsewhere) +H30 (chorioretinal inflammation) +H31 (other disorders of choroid) +H32 (chorioretinal disorders in diseases classified elsewhere) +H33 (retinal detachments and breaks) +H34 (retinal vascular occlusions) +H35 (other retinal disorders) +H36 (retinal disorders in diseases classified elsewhere) +H40 (glaucoma) +H42 (glaucoma in diseases classified elsewhere) +H43 (disorders of vitreous body) +H44 (disorders of globe) +H45 (disorders of vitreous body and globe in diseases classified elsewhere) +H46 (optic neuritis) +H47 (other disorders of optic [2nd] nerve and visual pathways) +H48 (disorders of optic [2nd] nerve and visual pathways in diseases classified elsewhere) +H49 (paralytic strabismus) +H50 (other strabismus) +H51 (other disorders of binocular movement) +H52 (disorders of refraction and accommodation) +H53 (visual disturbances) +H54 (blindness and low vision) +H55 (nystagmus and other irregular eye movements) +H57 (other disorders of eye and adnexa) +H58 (other disorders of eye and adnexa in diseases classified elsewhere) +H59 (postprocedural disorders of eye and adnexa, not elsewhere classified) +H60 (otitis externa) +H61 (other disorders of external ear) +H62 (disorders of external ear in diseases classified elsewhere) +H65 (nonsuppurative otitis media) +H66 (suppurative and unspecified otitis media) +H67 (otitis media in diseases classified elsewhere) +H68 (eustachian salpingitis and obstruction) +H69 (other disorders of eustachian tube) +H70 (mastoiditis and related conditions) +H71 (cholesteatoma of middle ear) +H72 (perforation of tympanic membrane) +H73 (other disorders of tympanic membrane) +H74 (other disorders of middle ear and mastoid) +H75 (other disorders of middle ear and mastoid in diseases classified elsewhere) +H80 (otosclerosis) +H81 (disorders of vestibular function) +H82 (vertiginous syndromes in diseases classified elsewhere) +H83 (other diseases of inner ear) +H90 (conductive and sensorineural hearing loss) +H91 (other hearing loss) +H92 (otalgia and effusion of ear) +H93 (other disorders of ear, not elsewhere classified) +H94 (other disorders of ear in diseases classified elsewhere) +H95 (postprocedural disorders of ear and mastoid process, not elsewhere classified) +I00 (rheumatic fever without mention of heart involvement) +I01 (rheumatic fever with heart involvement) +I02 (rheumatic chorea) +I05 (rheumatic mitral valve diseases) +I06 (rheumatic aortic valve diseases) +I07 (rheumatic tricuspid valve diseases) +I08 (multiple valve diseases) +I09 (other rheumatic heart diseases) +I10 (essential (primary) hypertension) +I11 (hypertensive heart disease) +I12 (hypertensive renal disease) +I13 (hypertensive heart and renal disease) +I15 (secondary hypertension) +I20 (angina pectoris) +I21 (acute myocardial infarction) +I22 (subsequent myocardial infarction) +I23 (certain current complications following acute myocardial infarction) +I24 (other acute ischaemic heart diseases) +I25 (chronic ischaemic heart disease) +I26 (pulmonary embolism) +I27 (other pulmonary heart diseases) +I28 (other diseases of pulmonary vessels) +I30 (acute pericarditis) +I31 (other diseases of pericardium) +I32 (pericarditis in diseases classified elsewhere) +I33 (acute and subacute endocarditis) +I34 (nonrheumatic mitral valve disorders) +I35 (nonrheumatic aortic valve disorders) +I36 (nonrheumatic tricuspid valve disorders) +I37 (pulmonary valve disorders) +I38 (endocarditis, valve unspecified) +I39 (endocarditis and heart valve disorders in diseases classified elsewhere) +I40 (acute myocarditis) +I41 (myocarditis in diseases classified elsewhere) +I42 (cardiomyopathy) +I43 (cardiomyopathy in diseases classified elsewhere) +I44 (atrioventricular and left bundle-branch block) +I45 (other conduction disorders) +I46 (cardiac arrest) +I47 (paroxysmal tachycardia) +I48 (atrial fibrillation and flutter) +I49 (other cardiac arrhythmias) +I50 (heart failure) +I51 (complications and ill-defined descriptions of heart disease) +I52 (other heart disorders in diseases classified elsewhere) +I60 (subarachnoid haemorrhage) +I61 (intracerebral haemorrhage) +I62 (other nontraumatic intracranial haemorrhage) +I63 (cerebral infarction) +I64 (stroke, not specified as haemorrhage or infarction) +I65 (occlusion and stenosis of precerebral arteries, not resulting in cerebral infarction) +I66 (occlusion and stenosis of cerebral arteries, not resulting in cerebral infarction) +I67 (other cerebrovascular diseases) +I68 (cerebrovascular disorders in diseases classified elsewhere) +I69 (sequelae of cerebrovascular disease) +I70 (atherosclerosis) +I71 (aortic aneurysm and dissection) +I72 (other aneurysm) +I73 (other peripheral vascular diseases) +I74 (arterial embolism and thrombosis) +I77 (other disorders of arteries and arterioles) +I78 (diseases of capillaries) +I79 (disorders of arteries, arterioles and capillaries in diseases classified elsewhere) +I80 (phlebitis and thrombophlebitis) +I81 (portal vein thrombosis) +I82 (other venous embolism and thrombosis) +I83 (varicose veins of lower extremities) +I84 (haemorrhoids) +I85 (oesophageal varices) +I86 (varicose veins of other sites) +I87 (other disorders of veins) +I88 (nonspecific lymphadenitis) +I89 (other non-infective disorders of lymphatic vessels and lymph nodes) +I95 (hypotension) +I97 (postprocedural disorders of circulatory system, not elsewhere classified) +I98 (other disorders of circulatory system in diseases classified elsewhere) +I99 (other and unspecified disorders of circulatory system) +J00 (acute nasopharyngitis [common cold]) +J01 (acute sinusitis) +J02 (acute pharyngitis) +J03 (acute tonsillitis) +J04 (acute laryngitis and tracheitis) +J05 (acute obstructive laryngitis [croup] and epiglottitis) +J06 (acute upper respiratory infections of multiple and unspecified sites) +J09 (influenza due to certain identified influenza virus) +J10 (influenza due to identified influenza virus) +J11 (influenza, virus not identified) +J12 (viral pneumonia, not elsewhere classified) +J13 (pneumonia due to streptococcus pneumoniae) +J14 (pneumonia due to haemophilus influenzae) +J15 (bacterial pneumonia, not elsewhere classified) +J16 (pneumonia due to other infectious organisms, not elsewhere classified) +J17 (pneumonia in diseases classified elsewhere) +J18 (pneumonia, organism unspecified) +J20 (acute bronchitis) +J21 (acute bronchiolitis) +J22 (unspecified acute lower respiratory infection) +J30 (vasomotor and allergic rhinitis) +J31 (chronic rhinitis, nasopharyngitis and pharyngitis) +J32 (chronic sinusitis) +J33 (nasal polyp) +J34 (other disorders of nose and nasal sinuses) +J35 (chronic diseases of tonsils and adenoids) +J36 (peritonsillar abscess) +J37 (chronic laryngitis and laryngotracheitis) +J38 (diseases of vocal cords and larynx, not elsewhere classified) +J39 (other diseases of upper respiratory tract) +J40 (bronchitis, not specified as acute or chronic) +J41 (simple and mucopurulent chronic bronchitis) +J42 (unspecified chronic bronchitis) +J43 (emphysema) +J44 (other chronic obstructive pulmonary disease) +J45 (asthma) +J46 (status asthmaticus) +J47 (bronchiectasis) +J60 (coalworker's pneumoconiosis) +J61 (pneumoconiosis due to asbestos and other mineral fibres) +J62 (pneumoconiosis due to dust containing silica) +J63 (pneumoconiosis due to other inorganic dusts) +J64 (unspecified pneumoconiosis) +J66 (airway disease due to specific organic dust) +J67 (hypersensitivity pneumonitis due to organic dust) +J68 (respiratory conditions due to inhalation of chemicals, gases, fumes and vapours) +J69 (pneumonitis due to solids and liquids) +J70 (respiratory conditions due to other external agents) +J80 (adult respiratory distress syndrome) +J81 (pulmonary oedema) +J82 (pulmonary eosinophilia, not elsewhere classified) +J84 (other interstitial pulmonary diseases) +J85 (abscess of lung and mediastinum) +J86 (pyothorax) +J90 (pleural effusion, not elsewhere classified) +J91 (pleural effusion in conditions classified elsewhere) +J92 (pleural plaque) +J93 (pneumothorax) +J94 (other pleural conditions) +J95 (postprocedural respiratory disorders, not elsewhere classified) +J96 (respiratory failure, not elsewhere classified) +J98 (other respiratory disorders) +J99 (respiratory disorders in diseases classified elsewhere) +K00 (disorders of tooth development and eruption) +K01 (embedded and impacted teeth) +K02 (dental caries) +K03 (other diseases of hard tissues of teeth) +K04 (diseases of pulp and periapical tissues) +K05 (gingivitis and periodontal diseases) +K06 (other disorders of gingiva and edentulous alveolar ridge) +K07 (dentofacial anomalies [including malocclusion]) +K08 (other disorders of teeth and supporting structures) +K09 (cysts of oral region, not elsewhere classified) +K10 (other diseases of jaws) +K11 (diseases of salivary glands) +K12 (stomatitis and related lesions) +K13 (other diseases of lip and oral mucosa) +K14 (diseases of tongue) +K20 (oesophagitis) +K21 (gastro-oesophageal reflux disease) +K22 (other diseases of oesophagus) +K23 (disorders of oesophagus in diseases classified elsewhere) +K25 (gastric ulcer) +K26 (duodenal ulcer) +K27 (peptic ulcer, site unspecified) +K28 (gastrojejunal ulcer) +K29 (gastritis and duodenitis) +K30 (dyspepsia) +K31 (other diseases of stomach and duodenum) +K35 (acute appendicitis) +K36 (other appendicitis) +K37 (unspecified appendicitis) +K38 (other diseases of appendix) +K40 (inguinal hernia) +K41 (femoral hernia) +K42 (umbilical hernia) +K43 (ventral hernia) +K44 (diaphragmatic hernia) +K45 (other abdominal hernia) +K46 (unspecified abdominal hernia) +K50 (crohn's disease [regional enteritis]) +K51 (ulcerative colitis) +K52 (other non-infective gastro-enteritis and colitis) +K55 (vascular disorders of intestine) +K56 (paralytic ileus and intestinal obstruction without hernia) +K57 (diverticular disease of intestine) +K58 (irritable bowel syndrome) +K59 (other functional intestinal disorders) +K60 (fissure and fistula of anal and rectal regions) +K61 (abscess of anal and rectal regions) +K62 (other diseases of anus and rectum) +K63 (other diseases of intestine) +K64 (haemorrhoids and perianal venous thrombosis) +K65 (peritonitis) +K66 (other disorders of peritoneum) +K67 (disorders of peritoneum in infectious diseases classified elsewhere) +K70 (alcoholic liver disease) +K71 (toxic liver disease) +K72 (hepatic failure, not elsewhere classified) +K73 (chronic hepatitis, not elsewhere classified) +K74 (fibrosis and cirrhosis of liver) +K75 (other inflammatory liver diseases) +K76 (other diseases of liver) +K77 (liver disorders in diseases classified elsewhere) +K80 (cholelithiasis) +K81 (cholecystitis) +K82 (other diseases of gallbladder) +K83 (other diseases of biliary tract) +K85 (acute pancreatitis) +K86 (other diseases of pancreas) +K87 (disorders of gallbladder, biliary tract and pancreas in diseases classified elsewhere) +K90 (intestinal malabsorption) +K91 (postprocedural disorders of digestive system, not elsewhere classified) +K92 (other diseases of digestive system) +K93 (disorders of other digestive organs in diseases classified elsewhere) +L00 (staphylococcal scalded skin syndrome) +L01 (impetigo) +L02 (cutaneous abscess, furuncle and carbuncle) +L03 (cellulitis) +L04 (acute lymphadenitis) +L05 (pilonidal cyst) +L08 (other local infections of skin and subcutaneous tissue) +L10 (pemphigus) +L11 (other acantholytic disorders) +L12 (pemphigoid) +L13 (other bullous disorders) +L14 (bullous disorders in diseases classified elsewhere) +L20 (atopic dermatitis) +L21 (seborrhoeic dermatitis) +L22 (diaper [napkin] dermatitis) +L23 (allergic contact dermatitis) +L24 (irritant contact dermatitis) +L25 (unspecified contact dermatitis) +L26 (exfoliative dermatitis) +L27 (dermatitis due to substances taken internally) +L28 (lichen simplex chronicus and prurigo) +L29 (pruritus) +L30 (other dermatitis) +L40 (psoriasis) +L41 (parapsoriasis) +L42 (pityriasis rosea) +L43 (lichen planus) +L44 (other papulosquamous disorders) +L50 (urticaria) +L51 (erythema multiforme) +L52 (erythema nodosum) +L53 (other erythematous conditions) +L54 (erythema in diseases classified elsewhere) +L55 (sunburn) +L56 (other acute skin changes due to ultraviolet radiation) +L57 (skin changes due to chronic exposure to nonionising radiation) +L58 (radiodermatitis) +L59 (other disorders of skin and subcutaneous tissue related to radiation) +L60 (nail disorders) +L62 (nail disorders in diseases classified elsewhere) +L63 (alopecia areata) +L64 (androgenic alopecia) +L65 (other nonscarring hair loss) +L66 (cicatricial alopecia [scarring hair loss]) +L67 (hair colour and hair shaft abnormalities) +L68 (hypertrichosis) +L70 (acne) +L71 (rosacea) +L72 (follicular cysts of skin and subcutaneous tissue) +L73 (other follicular disorders) +L74 (eccrine sweat disorders) +L75 (apocrine sweat disorders) +L80 (vitiligo) +L81 (other disorders of pigmentation) +L82 (seborrhoeic keratosis) +L83 (acanthosis nigricans) +L84 (corns and callosities) +L85 (other epidermal thickening) +L86 (keratoderma in diseases classified elsewhere) +L87 (transepidermal elimination disorders) +L88 (pyoderma gangrenosum) +L89 (decubitus ulcer) +L90 (atrophic disorders of skin) +L91 (hypertrophic disorders of skin) +L92 (granulomatous disorders of skin and subcutaneous tissue) +L93 (lupus erythematosus) +L94 (other localised connective tissue disorders) +L95 (vasculitis limited to skin, not elsewhere classified) +L97 (ulcer of lower limb, not elsewhere classified) +L98 (other disorders of skin and subcutaneous tissue, not elsewhere classified) +L99 (other disorders of skin and subcutaneous tissue in diseases classified elsewhere) +M00 (pyogenic arthritis) +M01 (direct infections of joint in infectious and parasitic diseases classified elsewhere) +M02 (reactive arthropathies) +M03 (postinfective and reactive arthropathies in diseases classified elsewhere) +M05 (seropositive rheumatoid arthritis) +M06 (other rheumatoid arthritis) +M07 (psoriatic and enteropathic arthropathies) +M08 (juvenile arthritis) +M09 (juvenile arthritis in diseases classified elsewhere) +M10 (gout) +M11 (other crystal arthropathies) +M12 (other specific arthropathies) +M13 (other arthritis) +M14 (arthropathies in other diseases classified elsewhere) +M15 (polyarthrosis) +M16 (coxarthrosis [arthrosis of hip]) +M17 (gonarthrosis [arthrosis of knee]) +M18 (arthrosis of first carpometacarpal joint) +M19 (other arthrosis) +M20 (acquired deformities of fingers and toes) +M21 (other acquired deformities of limbs) +M22 (disorders of patella) +M23 (internal derangement of knee) +M24 (other specific joint derangements) +M25 (other joint disorders, not elsewhere classified) +M30 (polyarteritis nodosa and related conditions) +M31 (other necrotising vasculopathies) +M32 (systemic lupus erythematosus) +M33 (dermatopolymyositis) +M34 (systemic sclerosis) +M35 (other systemic involvement of connective tissue) +M36 (systemic disorders of connective tissue in diseases classified elsewhere) +M40 (kyphosis and lordosis) +M41 (scoliosis) +M42 (spinal osteochondrosis) +M43 (other deforming dorsopathies) +M45 (ankylosing spondylitis) +M46 (other inflammatory spondylopathies) +M47 (spondylosis) +M48 (other spondylopathies) +M49 (spondylopathies in diseases classified elsewhere) +M50 (cervical disk disorders) +M51 (other intervertebral disk disorders) +M53 (other dorsopathies, not elsewhere classified) +M54 (dorsalgia) +M60 (myositis) +M61 (calcification and ossification of muscle) +M62 (other disorders of muscle) +M63 (disorders of muscle in diseases classified elsewhere) +M65 (synovitis and tenosynovitis) +M66 (spontaneous rupture of synovium and tendon) +M67 (other disorders of synovium and tendon) +M68 (disorders of synovium and tendon in diseases classified elsewhere) +M70 (soft tissue disorders related to use, overuse and pressure) +M71 (other bursopathies) +M72 (fibroblastic disorders) +M73 (soft tissue disorders in diseases classified elsewhere) +M75 (shoulder lesions) +M76 (enthesopathies of lower limb, excluding foot) +M77 (other enthesopathies) +M79 (other soft tissue disorders, not elsewhere classified) +M80 (osteoporosis with pathological fracture) +M81 (osteoporosis without pathological fracture) +M82 (osteoporosis in diseases classified elsewhere) +M83 (adult osteomalacia) +M84 (disorders of continuity of bone) +M85 (other disorders of bone density and structure) +M86 (osteomyelitis) +M87 (osteonecrosis) +M88 (paget's disease of bone [osteitis deformans]) +M89 (other disorders of bone) +M90 (osteopathies in diseases classified elsewhere) +M91 (juvenile osteochondrosis of hip and pelvis) +M92 (other juvenile osteochondrosis) +M93 (other osteochondropathies) +M94 (other disorders of cartilage) +M95 (other acquired deformities of musculoskeletal system and connective tissue) +M96 (postprocedural musculoskeletal disorders, not elsewhere classified) +M99 (biomechanical lesions, not elsewhere classified) +N00 (acute nephritic syndrome) +N01 (rapidly progressive nephritic syndrome) +N02 (recurrent and persistent haematuria) +N03 (chronic nephritic syndrome) +N04 (nephrotic syndrome) +N05 (unspecified nephritic syndrome) +N06 (isolated proteinuria with specified morphological lesion) +N07 (hereditary nephropathy, not elsewhere classified) +N08 (glomerular disorders in diseases classified elsewhere) +N10 (acute tubulo-interstitial nephritis) +N11 (chronic tubulo-interstitial nephritis) +N12 (tubulo-interstitial nephritis, not specified as acute or chronic) +N13 (obstructive and reflux uropathy) +N14 (drug- and heavy-metal-induced tubulo-interstitial and tubular conditions) +N15 (other renal tubulo-interstitial diseases) +N16 (renal tubulo-interstitial disorders in diseases classified elsewhere) +N17 (acute renal failure) +N18 (chronic renal failure) +N19 (unspecified renal failure) +N20 (calculus of kidney and ureter) +N21 (calculus of lower urinary tract) +N22 (calculus of urinary tract in diseases classified elsewhere) +N23 (unspecified renal colic) +N25 (disorders resulting from impaired renal tubular function) +N26 (unspecified contracted kidney) +N27 (small kidney of unknown cause) +N28 (other disorders of kidney and ureter, not elsewhere classified) +N29 (other disorders of kidney and ureter in diseases classified elsewhere) +N30 (cystitis) +N31 (neuromuscular dysfunction of bladder, not elsewhere classified) +N32 (other disorders of bladder) +N33 (bladder disorders in diseases classified elsewhere) +N34 (urethritis and urethral syndrome) +N35 (urethral stricture) +N36 (other disorders of urethra) +N37 (urethral disorders in diseases classified elsewhere) +N39 (other disorders of urinary system) +N40 (hyperplasia of prostate) +N41 (inflammatory diseases of prostate) +N42 (other disorders of prostate) +N43 (hydrocele and spermatocele) +N44 (torsion of testis) +N45 (orchitis and epididymitis) +N46 (male infertility) +N47 (redundant prepuce, phimosis and paraphimosis) +N48 (other disorders of penis) +N49 (inflammatory disorders of male genital organs, not elsewhere classified) +N50 (other disorders of male genital organs) +N51 (disorders of male genital organs in diseases classified elsewhere) +N60 (benign mammary dysplasia) +N61 (inflammatory disorders of breast) +N62 (hypertrophy of breast) +N63 (unspecified lump in breast) +N64 (other disorders of breast) +N70 (salpingitis and oophoritis) +N71 (inflammatory disease of uterus, except cervix) +N72 (inflammatory disease of cervix uteri) +N73 (other female pelvic inflammatory diseases) +N74 (female pelvic inflammatory disorders in diseases classified elsewhere) +N75 (diseases of bartholin's gland) +N76 (other inflammation of vagina and vulva) +N77 (vulvovaginal ulceration and inflammation in diseases classified elsewhere) +N80 (endometriosis) +N81 (female genital prolapse) +N82 (fistulae involving female genital tract) +N83 (noninflammatory disorders of ovary, fallopian tube and broad ligament) +N84 (polyp of female genital tract) +N85 (other noninflammatory disorders of uterus, except cervix) +N86 (erosion and ectropion of cervix uteri) +N87 (dysplasia of cervix uteri) +N88 (other noninflammatory disorders of cervix uteri) +N89 (other noninflammatory disorders of vagina) +N90 (other noninflammatory disorders of vulva and perineum) +N91 (absent, scanty and rare menstruation) +N92 (excessive, frequent and irregular menstruation) +N93 (other abnormal uterine and vaginal bleeding) +N94 (pain and other conditions associated with female genital organs and menstrual cycle) +N95 (menopausal and other perimenopausal disorders) +N96 (habitual aborter) +N97 (female infertility) +N98 (complications associated with artificial fertilisation) +N99 (postprocedural disorders of genito-urinary system, not elsewhere classified) +O00 (ectopic pregnancy) +O01 (hydatidiform mole) +O02 (other abnormal products of conception) +O03 (spontaneous abortion) +O04 (medical abortion) +O05 (other abortion) +O06 (unspecified abortion) +O07 (failed attempted abortion) +O08 (complications following abortion and ectopic and molar pregnancy) +O10 (pre-existing hypertension complicating pregnancy, childbirth and the puerperium) +O11 (pre-existing hypertensive disorder with superimposed proteinuria) +O12 (gestational [pregnancy-induced] oedema and proteinuria without hypertension) +O13 (gestational [pregnancy-induced] hypertension without significant proteinuria) +O14 (gestational [pregnancy-induced] hypertension with significant proteinuria) +O15 (eclampsia) +O16 (unspecified maternal hypertension) +O20 (haemorrhage in early pregnancy) +O21 (excessive vomiting in pregnancy) +O22 (venous complications in pregnancy) +O23 (infections of genito-urinary tract in pregnancy) +O24 (diabetes mellitus in pregnancy) +O25 (malnutrition in pregnancy) +O26 (maternal care for other conditions predominantly related to pregnancy) +O28 (abnormal findings on antenatal screening of mother) +O29 (complications of anaesthesia during pregnancy) +O30 (multiple gestation) +O31 (complications specific to multiple gestation) +O32 (maternal care for known or suspected malpresentation of foetus) +O33 (maternal care for known or suspected disproportion) +O34 (maternal care for known or suspected abnormality of pelvic organs) +O35 (maternal care for known or suspected foetal abnormality and damage) +O36 (maternal care for other known or suspected foetal problems) +O40 (polyhydramnios) +O41 (other disorders of amniotic fluid and membranes) +O42 (premature rupture of membranes) +O43 (placental disorders) +O44 (placenta praevia) +O45 (premature separation of placenta [abruptio placentae]) +O46 (antepartum haemorrhage, not elsewhere classified) +O47 (false labour) +O48 (prolonged pregnancy) +O60 (preterm delivery) +O61 (failed induction of labour) +O62 (abnormalities of forces of labour) +O63 (long labour) +O64 (obstructed labour due to malposition and malpresentation of foetus) +O65 (obstructed labour due to maternal pelvic abnormality) +O66 (other obstructed labour) +O67 (labour and delivery complicated by intrapartum haemorrhage, not elsewhere classified) +O68 (labour and delivery complicated by foetal stress [distress]) +O69 (labour and delivery complicated by umbilical cord complications) +O70 (perineal laceration during delivery) +O71 (other obstetric trauma) +O72 (postpartum haemorrhage) +O73 (retained placenta and membranes, without haemorrhage) +O74 (complications of anaesthesia during labour and delivery) +O75 (other complications of labour and delivery, not elsewhere classified) +O80 (single spontaneous delivery) +O81 (single delivery by forceps and vacuum extractor) +O82 (single delivery by caesarean section) +O83 (other assisted single delivery) +O84 (multiple delivery) +O85 (puerperal sepsis) +O86 (other puerperal infections) +O87 (venous complications in the puerperium) +O88 (obstetric embolism) +O89 (complications of anaesthesia during the puerperium) +O90 (complications of the puerperium, not elsewhere classified) +O91 (infections of breast associated with childbirth) +O92 (other disorders of breast and lactation associated with childbirth) +O94 (sequelae of complication of pregnancy, childbirth and the puerperium) +O96 (death from any obstetric cause occurring more than 42 days but less than one year after delivery) +O98 (maternal infectious and parasitic diseases classifiable elsewhere but complicating pregnancy, childbirth and the puerperium) +O99 (other maternal diseases classifiable elsewhere but complicating pregnancy, childbirth and the puerperium) +P00 (foetus and newborn affected by maternal conditions that may be unrelated to present pregnancy) +P02 (foetus and newborn affected by complications of placenta, cord and membranes) +P03 (foetus and newborn affected by other complications of labour and delivery) +P04 (foetus and newborn affected by noxious influences transmitted via placenta or breast milk) +P05 (slow foetal growth and foetal malnutrition) +P07 (disorders related to short gestation and low birth weight, not elsewhere classified) +P08 (disorders related to long gestation and high birth weight) +P10 (intracranial laceration and haemorrhage due to birth injury) +P11 (other birth injuries to central nervous system) +P12 (birth injury to scalp) +P13 (birth injury to skeleton) +P14 (birth injury to peripheral nervous system) +P15 (other birth injuries) +P20 (intra-uterine hypoxia) +P21 (birth asphyxia) +P22 (respiratory distress of newborn) +P23 (congenital pneumonia) +P24 (neonatal aspiration syndromes) +P25 (interstitial emphysema and related conditions originating in the perinatal period) +P26 (pulmonary haemorrhage originating in the perinatal period) +P27 (chronic respiratory disease originating in the perinatal period) +P28 (other respiratory conditions originating in the perinatal period) +P29 (cardiovascular disorders originating in the perinatal period) +P35 (congenital viral diseases) +P36 (bacterial sepsis of newborn) +P37 (other congenital infectious and parasitic diseases) +P38 (omphalitis of newborn with or without mild haemorrhage) +P39 (other infections specific to the perinatal period) +P50 (foetal blood loss) +P51 (umbilical haemorrhage of newborn) +P52 (intracranial nontraumatic haemorrhage of foetus and newborn) +P53 (haemorrhagic disease of foetus and newborn) +P54 (other neonatal haemorrhages) +P55 (haemolytic disease of foetus and newborn) +P58 (neonatal jaundice due to other excessive haemolysis) +P59 (neonatal jaundice from other and unspecified causes) +P61 (other perinatal haematological disorders) +P70 (transitory disorders of carbohydrate metabolism specific to foetus and newborn) +P71 (transitory neonatal disorders of calcium and magnesium metabolism) +P78 (other perinatal digestive system disorders) +P83 (other conditions of integument specific to foetus and newborn) +P91 (other disturbances of cerebral status of newborn) +P92 (feeding problems of newborn) +P94 (disorders of muscle tone of newborn) +P95 (foetal death of unspecified cause) +P96 (other conditions originating in the perinatal period) +Q00 (anencephaly and similar malformations) +Q01 (encephalocele) +Q02 (microcephaly) +Q03 (congenital hydrocephalus) +Q04 (other congenital malformations of brain) +Q05 (spina bifida) +Q06 (other congenital malformations of spinal cord) +Q07 (other congenital malformations of nervous system) +Q10 (congenital malformations of eyelid, lachrymal apparatus and orbit) +Q11 (anophthalmos, microphthalmos and macrophthalmos) +Q12 (congenital lens malformations) +Q13 (congenital malformations of anterior segment of eye) +Q14 (congenital malformations of posterior segment of eye) +Q15 (other congenital malformations of eye) +Q16 (congenital malformations of ear causing impairment of hearing) +Q17 (other congenital malformations of ear) +Q18 (other congenital malformations of face and neck) +Q20 (congenital malformations of cardiac chambers and connexions) +Q21 (congenital malformations of cardiac septa) +Q22 (congenital malformations of pulmonary and tricuspid valves) +Q23 (congenital malformations of aortic and mitral valves) +Q24 (other congenital malformations of heart) +Q25 (congenital malformations of great arteries) +Q26 (congenital malformations of great veins) +Q27 (other congenital malformations of peripheral vascular system) +Q28 (other congenital malformations of circulatory system) +Q30 (congenital malformations of nose) +Q31 (congenital malformations of larynx) +Q32 (congenital malformations of trachea and bronchus) +Q33 (congenital malformations of lung) +Q34 (other congenital malformations of respiratory system) +Q35 (cleft palate) +Q36 (cleft lip) +Q37 (cleft palate with cleft lip) +Q38 (other congenital malformations of tongue, mouth and pharynx) +Q39 (congenital malformations of oesophagus) +Q40 (other congenital malformations of upper alimentary tract) +Q41 (congenital absence, atresia and stenosis of small intestine) +Q42 (congenital absence, atresia and stenosis of large intestine) +Q43 (other congenital malformations of intestine) +Q44 (congenital malformations of gallbladder, bile ducts and liver) +Q45 (other congenital malformations of digestive system) +Q50 (congenital malformations of ovaries, fallopian tubes and broad ligaments) +Q51 (congenital malformations of uterus and cervix) +Q52 (other congenital malformations of female genitalia) +Q53 (undescended testicle) +Q54 (hypospadias) +Q55 (other congenital malformations of male genital organs) +Q56 (indeterminate sex and pseudohermaphroditism) +Q60 (renal agenesis and other reduction defects of kidney) +Q61 (cystic kidney disease) +Q62 (congenital obstructive defects of renal pelvis and congenital malformations of ureter) +Q63 (other congenital malformations of kidney) +Q64 (other congenital malformations of urinary system) +Q65 (congenital deformities of hip) +Q66 (congenital deformities of feet) +Q67 (congenital musculoskeletal deformities of head, face, spine and chest) +Q68 (other congenital musculoskeletal deformities) +Q69 (polydactyly) +Q70 (syndactyly) +Q71 (reduction defects of upper limb) +Q72 (reduction defects of lower limb) +Q73 (reduction defects of unspecified limb) +Q74 (other congenital malformations of limb(s)) +Q75 (other congenital malformations of skull and face bones) +Q76 (congenital malformations of spine and bony thorax) +Q77 (osteochondrodysplasia with defects of growth of tubular bones and spine) +Q78 (other osteochondrodysplasias) +Q79 (congenital malformations of musculoskeletal system, not elsewhere classified) +Q80 (congenital ichthyosis) +Q81 (epidermolysis bullosa) +Q82 (other congenital malformations of skin) +Q83 (congenital malformations of breast) +Q84 (other congenital malformations of integument) +Q85 (phakomatoses, not elsewhere classified) +Q86 (congenital malformation syndromes due to known exogenous causes, not elsewhere classified) +Q87 (other specified congenital malformation syndromes affecting multiple systems) +Q89 (other congenital malformations, not elsewhere classified) +Q90 (down's syndrome) +Q91 (edwards' syndrome and patau's syndrome) +Q92 (other trisomies and partial trisomies of the autosomes, not elsewhere classified) +Q93 (monosomies and deletions from the autosomes, not elsewhere classified) +Q95 (balanced rearrangements and structural markers, not elsewhere classified) +Q96 (turner's syndrome) +Q97 (other sex chromosome abnormalities, female phenotype, not elsewhere classified) +Q98 (other sex chromosome abnormalities, male phenotype, not elsewhere classified) +Q99 (other chromosome abnormalities, not elsewhere classified) +CXX Unknown Cancer +C00 Malignant neoplasm of lip +C01 Malignant neoplasm of base of tongue +C02 Malignant neoplasm of other and unspecified parts of tongue +C03 Malignant neoplasm of gum +C04 Malignant neoplasm of floor of mouth +C05 Malignant neoplasm of palate +C06 Malignant neoplasm of other and unspecified parts of mouth +C07 Malignant neoplasm of parotid gland +C08 Malignant neoplasm of other and unspecified major salivary glands +C09 Malignant neoplasm of tonsil +C10 Malignant neoplasm of oropharynx +C11 Malignant neoplasm of nasopharynx +C12 Malignant neoplasm of pyriform sinus +C13 Malignant neoplasm of hypopharynx +C14 Malignant neoplasm of other and ill-defined sites in the lip, oral cavity and pharynx +C15 Malignant neoplasm of oesophagus +C16 Malignant neoplasm of stomach +C17 Malignant neoplasm of small intestine +C18 Malignant neoplasm of colon +C19 Malignant neoplasm of rectosigmoid junction +C20 Malignant neoplasm of rectum +C21 Malignant neoplasm of anus and anal canal +C22 Malignant neoplasm of liver and intrahepatic bile ducts +C23 Malignant neoplasm of gallbladder +C24 Malignant neoplasm of other and unspecified parts of biliary tract +C25 Malignant neoplasm of pancreas +C26 Malignant neoplasm of other and ill-defined digestive organs +C30 Malignant neoplasm of nasal cavity and middle ear +C31 Malignant neoplasm of accessory sinuses +C32 Malignant neoplasm of larynx +C33 Malignant neoplasm of trachea +C34 Malignant neoplasm of bronchus and lung +C37 Malignant neoplasm of thymus +C38 Malignant neoplasm of heart, mediastinum and pleura +C39 Malignant neoplasm of other and ill-defined sites in the respiratory system and intrathoracic organs +C40 Malignant neoplasm of bone and articular cartilage of limbs +C41 Malignant neoplasm of bone and articular cartilage of other and unspecified sites +C42 hematopoietic and reticuloendothelial systems (ICD-O-3 specific) +C43 Malignant melanoma of skin +C44 Other malignant neoplasms of skin +C45 Mesothelioma +C46 Kaposi's sarcoma +C47 Malignant neoplasm of peripheral nerves and autonomic nervous system +C48 Malignant neoplasm of retroperitoneum and peritoneum +C49 Malignant neoplasm of other connective and soft tissue +C50 Malignant neoplasm of breast +C51 Malignant neoplasm of vulva +C52 Malignant neoplasm of vagina +C53 Malignant neoplasm of cervix uteri +C54 Malignant neoplasm of corpus uteri +C55 Malignant neoplasm of uterus, part unspecified +C56 Malignant neoplasm of ovary +C57 Malignant neoplasm of other and unspecified female genital organs +C58 Malignant neoplasm of placenta +C60 Malignant neoplasm of penis +C61 Malignant neoplasm of prostate +C62 Malignant neoplasm of testis +C63 Malignant neoplasm of other and unspecified male genital organs +C64 Malignant neoplasm of kidney, except renal pelvis +C65 Malignant neoplasm of renal pelvis +C66 Malignant neoplasm of ureter +C67 Malignant neoplasm of bladder +C68 Malignant neoplasm of other and unspecified urinary organs +C69 Malignant neoplasm of eye and adnexa +C70 Malignant neoplasm of meninges +C71 Malignant neoplasm of brain +C72 Malignant neoplasm of spinal cord, cranial nerves and other parts of central nervous system +C73 Malignant neoplasm of thyroid gland +C74 Malignant neoplasm of adrenal gland +C75 Malignant neoplasm of other endocrine glands and related structures +C76 Malignant neoplasm of other and ill-defined sites +C77 Secondary and unspecified malignant neoplasm of lymph nodes +C78 Secondary malignant neoplasm of respiratory and digestive organs +C79 Secondary malignant neoplasm of other sites +C80 Malignant neoplasm without specification of site +C81 Hodgkin's disease +C82 Follicular [nodular] non-Hodgkin's lymphoma +C83 Diffuse non-Hodgkin's lymphoma +C84 Peripheral and cutaneous T-cell lymphomas +C85 Other and unspecified types of non-Hodgkin's lymphoma +C86 Other specified types of T/NK-cell lymphoma +C88 Malignant immunoproliferative diseases +C90 Multiple myeloma and malignant plasma cell neoplasms +C91 Lymphoid leukaemia +C92 Myeloid leukaemia +C93 Monocytic leukaemia +C94 Other leukaemias of specified cell type +C95 Leukaemia of unspecified cell type +C96 Other and unspecified malignant neoplasms of lymphoid, haematopoietic and related tissue +C97 Malignant neoplasms of independent (primary) multiple sites +D00 Carcinoma in situ of oral cavity, oesophagus and stomach +D01 Carcinoma in situ of other and unspecified digestive organs +D02 Carcinoma in situ of middle ear and respiratory system +D03 Melanoma in situ +D04 Carcinoma in situ of skin +D05 Carcinoma in situ of breast +D06 Carcinoma in situ of cervix uteri +D07 Carcinoma in situ of other and unspecified genital organs +D09 Carcinoma in situ of other and unspecified sites +D10 Benign neoplasm of mouth and pharynx +D11 Benign neoplasm of major salivary glands +D12 Benign neoplasm of colon, rectum, anus and anal canal +D13 Benign neoplasm of other and ill-defined parts of digestive system +D15 Benign neoplasm of other and unspecified intrathoracic organs +D16 Benign neoplasm of bone and articular cartilage +D18 Haemangioma and lymphangioma, any site +D27 Benign neoplasm of ovary +D30 Benign neoplasm of urinary organs +D32 Benign neoplasm of meninges +D33 Benign neoplasm of brain and other parts of central nervous system +D34 Benign neoplasm of thyroid gland +D35 Benign neoplasm of other and unspecified endocrine glands +D36 Benign neoplasm of other and unspecified sites +D37 Neoplasm of uncertain or unknown behaviour of oral cavity and digestive organs +D38 Neoplasm of uncertain or unknown behaviour of middle ear and respiratory and intrathoracic organs +D39 Neoplasm of uncertain or unknown behaviour of female genital organs +D40 Neoplasm of uncertain or unknown behaviour of male genital organs +D41 Neoplasm of uncertain or unknown behaviour of urinary organs +D42 Neoplasm of uncertain or unknown behaviour of meninges +D43 Neoplasm of uncertain or unknown behaviour of brain and central nervous system +D44 Neoplasm of uncertain or unknown behaviour of endocrine glands +D45 Polycythaemia vera +D46 Myelodysplastic syndromes +D47 Other neoplasms of uncertain or unknown behaviour of lymphoid, haematopoietic and related tissue +D48 Neoplasm of uncertain or unknown behaviour of other and unspecified sites +Death diff --git a/losses.py b/losses.py new file mode 100644 index 0000000..51883a4 --- /dev/null +++ b/losses.py @@ -0,0 +1,400 @@ +from __future__ import annotations + +from typing import Iterable + +import torch +import torch.nn as nn +import torch.nn.functional as F + + +PAD_IDX = 0 +CHECKUP_IDX = 1 +NO_EVENT_IDX = 2 + + +def _make_ignore_mask( + vocab_size: int, + ignored_idx: Iterable[int], + device: torch.device, +) -> torch.Tensor: + ignore_mask = torch.zeros(vocab_size, dtype=torch.bool, device=device) + for idx in ignored_idx: + idx = int(idx) + if 0 <= idx < vocab_size: + ignore_mask[idx] = True + return ignore_mask + + +def _valid_vocab_mask( + vocab_size: int, + ignored_idx: Iterable[int], + device: torch.device, +) -> torch.Tensor: + return ~_make_ignore_mask(vocab_size, ignored_idx, device) + + +def _zero_loss_like(logits: torch.Tensor) -> torch.Tensor: + return logits.sum() * 0.0 + + +class Delphi2MLoss(nn.Module): + """Next-token plus exponential time-to-next-token supervision.""" + + def __init__( + self, + t_min: float = 1.0 / 365.25, + ignored_tokens: Iterable[int] | None = None, + exclude_ignored_from_intensity: bool = True, + max_exp_input: float = 60.0, + ce_weight: float = 1.0, + time_weight: float = 1.0, + ): + super().__init__() + self.t_min = float(t_min) + self.ignored_tokens = ( + [PAD_IDX, CHECKUP_IDX] + if ignored_tokens is None + else [int(x) for x in ignored_tokens] + ) + self.exclude_ignored_from_intensity = bool(exclude_ignored_from_intensity) + self.max_exp_input = float(max_exp_input) + self.ce_weight = float(ce_weight) + self.time_weight = float(time_weight) + + def forward( + self, + logits: torch.Tensor, + target_events: torch.Tensor, + target_times: torch.Tensor, + current_times: torch.Tensor, + padding_mask: torch.Tensor, + return_components: bool = False, + ) -> torch.Tensor | tuple[torch.Tensor, dict[str, torch.Tensor]]: + if logits.dim() != 3: + raise ValueError(f"logits must be (B, L, K), got {tuple(logits.shape)}") + bsz, seq_len, vocab_size = logits.shape + + expected = (bsz, seq_len) + if target_events.shape != expected: + raise ValueError(f"target_events must be {expected}, got {tuple(target_events.shape)}") + if target_times.shape != expected: + raise ValueError(f"target_times must be {expected}, got {tuple(target_times.shape)}") + if current_times.shape != expected: + raise ValueError(f"current_times must be {expected}, got {tuple(current_times.shape)}") + if padding_mask.shape != expected: + raise ValueError(f"padding_mask must be {expected}, got {tuple(padding_mask.shape)}") + + valid_mask = padding_mask.bool() + for idx in self.ignored_tokens: + valid_mask = valid_mask & (target_events != int(idx)) + valid_mask = valid_mask & (target_events > PAD_IDX) + + if not valid_mask.any(): + total_loss = _zero_loss_like(logits) + if return_components: + return total_loss, { + "ce": total_loss.detach(), + "time": total_loss.detach(), + "total": total_loss.detach(), + } + return total_loss + + logits_valid = logits[valid_mask] + target_events_valid = target_events[valid_mask] + target_times_valid = target_times[valid_mask] + current_times_valid = current_times[valid_mask] + + logits_safe = torch.nan_to_num( + logits_valid, + nan=0.0, + posinf=self.max_exp_input, + neginf=-self.max_exp_input, + ) + + loss_ce = F.cross_entropy( + logits_safe, + target_events_valid, + reduction="mean", + ) + + logits_for_lse = logits_safe + if self.exclude_ignored_from_intensity: + ignore_mask = _make_ignore_mask(vocab_size, self.ignored_tokens, logits.device) + logits_for_lse = logits_safe.masked_fill(ignore_mask.unsqueeze(0), float("-inf")) + + log_lambda_total = torch.logsumexp(logits_for_lse, dim=-1) + log_lambda_total = -torch.log(torch.exp(-log_lambda_total) + self.t_min) + + dt = torch.clamp(target_times_valid - current_times_valid, min=self.t_min) + log_dt_inv = -torch.log(dt + self.t_min) + loss_dt = -( + log_lambda_total + - torch.exp( + torch.clamp(log_lambda_total - log_dt_inv, max=self.max_exp_input) + ) + ) + loss_dt = loss_dt.mean() + + total_loss = self.ce_weight * loss_ce + self.time_weight * loss_dt + if return_components: + return total_loss, { + "ce": loss_ce.detach(), + "time": loss_dt.detach(), + "total": total_loss.detach(), + } + return total_loss + + +class UniqueTimeSetExponentialLoss(nn.Module): + """Next distinct timestamp event-set supervision with sum reduction.""" + + def __init__( + self, + ignored_idx: Iterable[int] = (PAD_IDX, CHECKUP_IDX), + t_min: float = 1.0 / 365.25, + max_exp_input: float = 60.0, + exclude_ignored_from_intensity: bool = True, + ): + super().__init__() + self.ignored_idx = [int(x) for x in ignored_idx] + self.t_min = float(t_min) + self.max_exp_input = float(max_exp_input) + self.exclude_ignored_from_intensity = bool(exclude_ignored_from_intensity) + + def forward( + self, + logits: torch.Tensor, + target_multi_hot: torch.Tensor, + target_dt_unique: torch.Tensor, + readout_mask: torch.Tensor, + return_components: bool = False, + ) -> torch.Tensor | tuple[torch.Tensor, dict[str, torch.Tensor]]: + if logits.dim() != 3: + raise ValueError(f"logits must be (B, L, K), got {tuple(logits.shape)}") + bsz, seq_len, vocab_size = logits.shape + + if target_multi_hot.shape != (bsz, seq_len, vocab_size): + raise ValueError( + "target_multi_hot must match logits shape, " + f"got {tuple(target_multi_hot.shape)} vs {tuple(logits.shape)}" + ) + if target_dt_unique.shape != (bsz, seq_len): + raise ValueError( + f"target_dt_unique must be {(bsz, seq_len)}, got {tuple(target_dt_unique.shape)}" + ) + if readout_mask.shape != (bsz, seq_len): + raise ValueError(f"readout_mask must be {(bsz, seq_len)}, got {tuple(readout_mask.shape)}") + + ignore_mask = _make_ignore_mask(vocab_size, self.ignored_idx, logits.device) + + num_targets = target_multi_hot[:, :, ~ignore_mask].sum(dim=-1) + valid_mask = readout_mask.bool() & (num_targets > 0) + + if not valid_mask.any(): + total_loss = _zero_loss_like(logits) + if return_components: + return total_loss, { + "observed": total_loss.detach(), + "penalty": total_loss.detach(), + "total": total_loss.detach(), + } + return total_loss + + logits_safe = torch.nan_to_num( + logits[valid_mask], + nan=0.0, + posinf=self.max_exp_input, + neginf=-self.max_exp_input, + ) + target_valid = target_multi_hot[valid_mask].to(logits_safe.dtype) + target_valid[:, ignore_mask] = 0.0 + + observed_term = (logits_safe * target_valid).sum(dim=-1) + penalty_scale = target_valid.sum(dim=-1) + + logits_for_lse = logits_safe + if self.exclude_ignored_from_intensity: + logits_for_lse = logits_safe.masked_fill(ignore_mask.unsqueeze(0), float("-inf")) + + dt_clamped = torch.clamp(target_dt_unique[valid_mask], min=self.t_min) + log_lambda_total = torch.logsumexp(logits_for_lse, dim=-1) + log_penalty = log_lambda_total + dt_clamped.log() + penalty = torch.exp(torch.clamp(log_penalty, max=self.max_exp_input)) + + observed_loss = -observed_term + penalty_loss = penalty_scale * penalty + total_loss = (observed_loss + penalty_loss).mean() + + if return_components: + return total_loss, { + "observed": observed_loss.mean().detach(), + "penalty": penalty_loss.mean().detach(), + "total": total_loss.detach(), + } + return total_loss + + +class ExponentialLoss(nn.Module): + """Query-conditioned all-future-event exponential point-process loss.""" + + def __init__( + self, + ignored_idx: Iterable[int] = (PAD_IDX, CHECKUP_IDX), + eps: float = 1e-8, + ): + super().__init__() + self.ignored_idx = tuple(int(i) for i in ignored_idx) + self.eps = eps + + def forward( + self, + logits: torch.Tensor, + targets: torch.Tensor, + exposure: torch.Tensor, + ) -> torch.Tensor: + _, vocab_size = logits.shape + rate = F.softplus(logits) + self.eps + valid_vocab = _valid_vocab_mask(vocab_size, self.ignored_idx, logits.device) + + penalty = exposure.to(rate.dtype) * rate[:, valid_vocab].sum(dim=-1) + target_valid = torch.ones_like(targets, dtype=torch.bool, device=logits.device) + for idx in self.ignored_idx: + target_valid &= targets != idx + + safe_targets = targets.clamp(min=0, max=vocab_size - 1) + observed = rate.log().gather(1, safe_targets) + observed = (observed * target_valid.to(rate.dtype)).sum(dim=-1) + return (-observed + penalty).mean() + + +class WeibullLoss(nn.Module): + """Query-conditioned all-future-event Weibull point-process loss.""" + + def __init__( + self, + ignored_idx: Iterable[int] = (PAD_IDX, CHECKUP_IDX), + eps: float = 1e-8, + ): + super().__init__() + self.ignored_idx = tuple(int(i) for i in ignored_idx) + self.eps = eps + + def forward( + self, + logits: torch.Tensor, + weibull_rho: torch.Tensor, + targets: torch.Tensor, + dt: torch.Tensor, + exposure: torch.Tensor, + ) -> torch.Tensor: + _, vocab_size = logits.shape + if weibull_rho is None: + raise ValueError("weibull_rho is required for WeibullLoss") + if weibull_rho.shape != logits.shape: + raise ValueError( + "weibull_rho must have the same shape as logits. " + f"Got logits={tuple(logits.shape)}, weibull_rho={tuple(weibull_rho.shape)}" + ) + + dtype = logits.dtype + rate = F.softplus(logits) + self.eps + rho = weibull_rho.to(device=logits.device, dtype=dtype).clamp_min(self.eps) + valid_vocab = _valid_vocab_mask(vocab_size, self.ignored_idx, logits.device) + + t_exp = exposure.to(dtype).clamp_min(self.eps).unsqueeze(1) + penalty = (rate * torch.pow(t_exp, rho))[:, valid_vocab].sum(dim=-1) + + target_valid = torch.ones_like(targets, dtype=torch.bool, device=logits.device) + for idx in self.ignored_idx: + target_valid &= targets != idx + + safe_targets = targets.clamp(min=0, max=vocab_size - 1) + target_rate = rate.gather(1, safe_targets) + target_rho = rho.gather(1, safe_targets) + target_dt = dt.to(dtype).clamp_min(self.eps) + log_intensity = ( + target_rate.log() + + target_rho.log() + + (target_rho - 1.0) * target_dt.log() + ) + observed = (log_intensity * target_valid.to(dtype)).sum(dim=-1) + return (-observed + penalty).mean() + + +class MixedLoss(nn.Module): + """Exponential diseases plus one Weibull death endpoint.""" + + def __init__( + self, + death_idx: int, + ignored_idx: Iterable[int] = (PAD_IDX, CHECKUP_IDX), + eps: float = 1e-8, + ): + super().__init__() + self.death_idx = int(death_idx) + self.ignored_idx = tuple(int(i) for i in ignored_idx) + self.eps = eps + + def forward( + self, + logits: torch.Tensor, + death_rho: torch.Tensor, + targets: torch.Tensor, + dt: torch.Tensor, + exposure: torch.Tensor, + ) -> torch.Tensor: + _, vocab_size = logits.shape + dtype = logits.dtype + rate = F.softplus(logits) + self.eps + + if death_rho.dim() == 2: + death_rho = death_rho.squeeze(-1) + death_rho = death_rho.to(device=logits.device, dtype=dtype).clamp_min(self.eps) + + valid_vocab = _valid_vocab_mask(vocab_size, self.ignored_idx, logits.device) + valid_disease_vocab = valid_vocab.clone() + valid_disease_vocab[self.death_idx] = False + + t_exp = exposure.to(dtype).clamp_min(self.eps) + disease_penalty = t_exp * rate[:, valid_disease_vocab].sum(dim=-1) + death_rate = rate[:, self.death_idx] + death_penalty = death_rate * torch.pow(t_exp, death_rho) + penalty = disease_penalty + death_penalty + + target_valid = torch.ones_like(targets, dtype=torch.bool, device=logits.device) + for idx in self.ignored_idx: + target_valid &= targets != idx + + disease_event_mask = target_valid & (targets != self.death_idx) + safe_targets = targets.clamp(min=0, max=vocab_size - 1) + disease_log_rate = rate.log().gather(1, safe_targets) + observed_disease = (disease_log_rate * disease_event_mask.to(dtype)).sum(dim=-1) + + death_event_mask = target_valid & (targets == self.death_idx) + death_observed = death_event_mask.any(dim=1) + death_dt = (dt.to(dtype).clamp_min(self.eps) * death_event_mask.to(dtype)).sum(dim=1) + death_log_intensity = ( + death_rate.log() + + death_rho.log() + + (death_rho - 1.0) * death_dt.clamp_min(self.eps).log() + ) + observed_death = death_log_intensity * death_observed.to(dtype) + + return (-observed_disease - observed_death + penalty).mean() + + +def build_loss(name: str, **kwargs) -> nn.Module: + name = name.lower() + if name in {"delphi2m", "d2m", "next_token"}: + return Delphi2MLoss(**kwargs) + if name in {"uts", "unique_time_set", "unique_time_exponential"}: + return UniqueTimeSetExponentialLoss(**kwargs) + if name in {"exponential", "query_exponential"}: + return ExponentialLoss(**kwargs) + if name in {"weibull", "query_weibull"}: + return WeibullLoss(**kwargs) + if name in {"mixed", "query_mixed"}: + return MixedLoss(**kwargs) + raise ValueError( + f"Unknown loss {name!r}. Available: delphi2m, uts, exponential, weibull, mixed." + ) diff --git a/models.py b/models.py new file mode 100644 index 0000000..d8b6e4e --- /dev/null +++ b/models.py @@ -0,0 +1,481 @@ +from dataclasses import dataclass + +import torch +import torch.nn as nn +import torch.nn.functional as F + +from backbones import ( + AgeSinusoidalEncoding, + GPTBlock, + GaussianRBFTimeBasis, + TimeRoPE, + TokenAutoDiscretization, +) +from targets import PAD_IDX + + +@dataclass +class DeepHealthOutput: + hidden: torch.Tensor + time_seq: torch.Tensor + padding_mask: torch.Tensor + event_len: int + + +class OtherInfoTokenizer(nn.Module): + PAD_KIND = 0 + CONT_KIND = 1 + CATE_KIND = 2 + + def __init__( + self, + n_embd: int, + n_types: int, + n_cont_types: int, + n_categories: int, + cont_type_ids: list[int], + n_value_kinds: int = 3, + n_bins: int = 16, + ): + super().__init__() + if len(cont_type_ids) != n_cont_types: + raise ValueError( + "cont_type_ids length must match n_cont_types, got " + f"{len(cont_type_ids)} vs {n_cont_types}" + ) + if n_types <= 0: + raise ValueError(f"n_types must include PAD and be > 0, got {n_types}") + if n_categories <= 0: + raise ValueError( + f"n_categories must include PAD and be > 0, got {n_categories}" + ) + if n_value_kinds <= self.CATE_KIND: + raise ValueError( + f"n_value_kinds must be > {self.CATE_KIND}, got {n_value_kinds}" + ) + + self.type_emb = nn.Embedding(n_types, n_embd, padding_idx=0) + self.kind_emb = nn.Embedding(n_value_kinds, n_embd, padding_idx=0) + self.cont_value_encoder = ( + TokenAutoDiscretization( + n_cont_types=n_cont_types, + n_bins=n_bins, + n_embd=n_embd, + ) + if n_cont_types > 0 + else None + ) + self.cate_value_emb = nn.Embedding( + n_categories, + n_embd, + padding_idx=0, + ) + + cont_type_index = torch.full((n_types,), -1, dtype=torch.long) + for idx, type_id in enumerate(cont_type_ids): + if type_id <= 0 or type_id >= n_types: + raise ValueError( + f"continuous type id {type_id} must be in [1, {n_types})" + ) + cont_type_index[type_id] = idx + self.register_buffer( + "cont_type_index", + cont_type_index, + persistent=False, + ) + self.reset_parameters() + + def reset_parameters(self) -> None: + nn.init.normal_(self.type_emb.weight, mean=0.0, std=0.02) + nn.init.zeros_(self.type_emb.weight[0]) + nn.init.normal_(self.kind_emb.weight, mean=0.0, std=0.02) + nn.init.zeros_(self.kind_emb.weight[0]) + nn.init.normal_(self.cate_value_emb.weight, mean=0.0, std=0.02) + nn.init.zeros_(self.cate_value_emb.weight[0]) + + def forward( + self, + other_type: torch.LongTensor, + other_value: torch.Tensor, + other_value_kind: torch.LongTensor, + ) -> tuple[torch.Tensor, torch.Tensor]: + if other_type.shape != other_value.shape: + raise ValueError( + "other_type and other_value must have the same shape, got " + f"{tuple(other_type.shape)} vs {tuple(other_value.shape)}" + ) + if other_type.shape != other_value_kind.shape: + raise ValueError( + "other_type and other_value_kind must have the same shape, got " + f"{tuple(other_type.shape)} vs {tuple(other_value_kind.shape)}" + ) + + other_valid = other_type > 0 + type_emb = self.type_emb(other_type) + kind_emb = self.kind_emb(other_value_kind) + value_emb = torch.zeros_like(type_emb) + + cont_pos = other_valid & (other_value_kind == self.CONT_KIND) + if cont_pos.any(): + if self.cont_value_encoder is None: + raise ValueError("continuous tokens found but n_cont_types is 0") + cont_idx = self.cont_type_index[other_type[cont_pos]] + if (cont_idx < 0).any(): + bad_type = other_type[cont_pos][cont_idx < 0][0].item() + raise ValueError( + f"type_id={bad_type} is marked continuous but is not in " + "cont_type_ids" + ) + value_emb[cont_pos] = self.cont_value_encoder( + cont_type_idx=cont_idx, + value=other_value[cont_pos].to(type_emb.dtype), + ) + + cate_pos = other_valid & (other_value_kind == self.CATE_KIND) + if cate_pos.any(): + cate_id = other_value[cate_pos].long() + value_emb[cate_pos] = self.cate_value_emb(cate_id) + + out = type_emb + kind_emb + value_emb + out = out * other_valid.unsqueeze(-1).to(out.dtype) + return out, other_valid + + +class DeepHealth(nn.Module): + def __init__( + self, + vocab_size: int, + n_embd: int, + n_head: int, + n_hist_layer: int, + n_tab_layer: int, + n_types: int, + n_cont_types: int, + n_categories: int, + cont_type_ids: list[int], + n_value_kinds: int = 3, + n_bins: int = 16, + target_mode: str = "next_token", # "next_token" or "all_future" + time_mode: str = "relative", # "relative" or "absolute" + dist_mode: str = "exponential", # "exponential", "weibull" or "mixed" + extra_pool_reduce: str = "mean", + dropout: float = 0.0, + ): + super().__init__() + if target_mode not in ["next_token", "all_future"]: + raise ValueError( + "target_mode must be either 'next_token' or 'all_future'") + if time_mode not in ["relative", "absolute"]: + raise ValueError( + "time_mode must be either 'relative' or 'absolute'") + if dist_mode not in ["exponential", "weibull", "mixed"]: + raise ValueError( + "dist_mode must be either 'exponential', 'weibull' or 'mixed'") + if extra_pool_reduce not in {"mean", "sum"}: + raise ValueError("extra_pool_reduce must be either 'mean' or 'sum'") + self.token_embedding = nn.Embedding(vocab_size, n_embd, padding_idx=0) + self.gender_embedding = nn.Embedding( + 2, n_embd) # Assuming binary gender + self.tokenizer = OtherInfoTokenizer( + n_embd=n_embd, + n_types=n_types, + n_cont_types=n_cont_types, + n_categories=n_categories, + cont_type_ids=cont_type_ids, + n_value_kinds=n_value_kinds, + n_bins=n_bins, + ) + self.target_mode = target_mode + self.time_mode = time_mode + self.dist_mode = dist_mode + self.extra_pool_reduce = extra_pool_reduce + self.n_embd = n_embd + self.vocab_size = vocab_size + nn.init.normal_(self.token_embedding.weight, mean=0.0, std=0.02) + nn.init.zeros_(self.token_embedding.weight[0]) + nn.init.normal_(self.gender_embedding.weight, mean=0.0, std=0.02) + if dist_mode == "weibull": + self.rho_head = nn.Linear(n_embd, vocab_size) + nn.init.zeros_(self.rho_head.weight) + nn.init.constant_(self.rho_head.bias, 0.5413) + + if dist_mode == "mixed": + self.death_idx = vocab_size - 1 + self.rho_death_head = nn.Linear(n_embd, 1) + nn.init.zeros_(self.rho_death_head.weight) + nn.init.constant_(self.rho_death_head.bias, 0.5413) + + if time_mode == "absolute": + self.age_encoding = AgeSinusoidalEncoding(n_embd) + self.blocks = nn.ModuleList([ + GPTBlock( + n_embd=n_embd, + n_head=n_head, + use_time_rope=False, + use_rbf_bias=False, + mlp_dropout=dropout, + ) for _ in range(n_hist_layer) + ]) + self.rope = None + self.rbf = None + elif time_mode == "relative": + self.age_encoding = None + self.blocks = nn.ModuleList([ + GPTBlock( + n_embd=n_embd, + n_head=n_head, + use_time_rope=True, + use_rbf_bias=True, + mlp_dropout=dropout, + ) for _ in range(n_hist_layer) + ]) + self.rope = TimeRoPE(n_embd // n_head) + self.rbf = GaussianRBFTimeBasis(n_bases=16, max_time_diff=40.0) + + self.final_ln = nn.LayerNorm(n_embd) + self.risk_head = nn.Linear(n_embd, vocab_size, bias=False) + if target_mode == "next_token": + self.risk_head.weight = self.token_embedding.weight + self.query_token = nn.Parameter(torch.zeros(n_embd)) + nn.init.normal_(self.query_token, mean=0.0, std=0.02) + + def _make_history_attn_mask( + self, + padding_mask: torch.Tensor, + time_seq: torch.Tensor, + dtype: torch.dtype, + ) -> torch.Tensor: + valid_key = padding_mask[:, None, :] # (B, 1, L) + visible_by_time = time_seq[:, None, :] <= time_seq[:, :, None] + valid = valid_key & visible_by_time + return torch.zeros( + valid.shape, + device=valid.device, + dtype=dtype, + ).masked_fill(~valid, -1e4)[:, None, :, :] + + def _pool_other_by_time( + self, + h_other: torch.Tensor, + other_time: torch.Tensor, + other_mask: torch.Tensor, + ) -> tuple[torch.Tensor, torch.Tensor, torch.Tensor]: + batch_size, n_other, n_embd = h_other.shape + if n_other == 0: + empty_h = h_other.new_zeros(batch_size, 0, n_embd) + empty_t = other_time.new_zeros(batch_size, 0) + empty_m = torch.zeros(batch_size, 0, dtype=torch.bool, device=h_other.device) + return empty_h, empty_t, empty_m + + masked_time = other_time.masked_fill(~other_mask, float("inf")) + _sorted_time_with_pad, order = masked_time.sort(dim=1) + sorted_time = other_time.gather(1, order) + sorted_mask = other_mask.gather(1, order) + sorted_h = h_other.gather(1, order.unsqueeze(-1).expand(-1, -1, n_embd)) + + group_start = torch.zeros_like(sorted_mask) + group_start[:, 0] = sorted_mask[:, 0] + group_start[:, 1:] = sorted_mask[:, 1:] & ( + sorted_time[:, 1:] != sorted_time[:, :-1] + ) + group_id = group_start.long().cumsum(dim=1) - 1 + max_groups = int(group_start.sum(dim=1).max().item()) + + pooled_h = h_other.new_zeros(batch_size, max_groups, n_embd) + pooled_time = other_time.new_zeros(batch_size, max_groups) + pooled_mask = torch.zeros( + batch_size, + max_groups, + dtype=torch.bool, + device=h_other.device, + ) + if max_groups == 0: + return pooled_h, pooled_time, pooled_mask + + safe_group_id = group_id.clamp_min(0) + pooled_h.scatter_add_( + 1, + safe_group_id.unsqueeze(-1).expand_as(sorted_h), + sorted_h * sorted_mask.unsqueeze(-1).to(sorted_h.dtype), + ) + if self.extra_pool_reduce == "mean": + counts = h_other.new_zeros(batch_size, max_groups, 1) + counts.scatter_add_( + 1, + safe_group_id.unsqueeze(-1), + sorted_mask.unsqueeze(-1).to(h_other.dtype), + ) + pooled_h = pooled_h / counts.clamp_min(1.0) + + pooled_time.scatter_add_( + 1, + safe_group_id, + sorted_time * group_start.to(sorted_time.dtype), + ) + group_count = group_start.sum(dim=1) + arange_groups = torch.arange(max_groups, device=h_other.device) + pooled_mask = arange_groups.unsqueeze(0) < group_count.unsqueeze(1) + return pooled_h, pooled_time, pooled_mask + + def _forward_shared( + self, + event_seq: torch.LongTensor, + time_seq: torch.FloatTensor, + sex: torch.LongTensor, + mode: str, + padding_mask: torch.Tensor | None = None, + t_query: torch.FloatTensor | None = None, + other_type: torch.LongTensor | None = None, + other_value: torch.Tensor | None = None, + other_value_kind: torch.LongTensor | None = None, + other_time: torch.FloatTensor | None = None, + return_output: bool = False, + **unused_kwargs, + ) -> torch.Tensor | DeepHealthOutput: + if unused_kwargs: + unknown = ", ".join(sorted(unused_kwargs)) + raise TypeError(f"Unexpected DeepHealth forward arguments: {unknown}") + if mode not in {"next_token", "all_future"}: + raise ValueError("mode must be either 'next_token' or 'all_future'") + if mode == "all_future" and t_query is None: + raise ValueError("t_query is required when mode='all_future'") + if ( + other_type is None + or other_value is None + or other_value_kind is None + or other_time is None + ): + raise ValueError( + "DeepHealth expects other_type, other_value, " + "other_value_kind, and other_time." + ) + + if padding_mask is None: + padding_mask = event_seq > PAD_IDX + else: + padding_mask = padding_mask.to(device=event_seq.device, dtype=torch.bool) + + event_len = event_seq.size(1) + h_disease = self.token_embedding(event_seq) + t_disease = time_seq + + if other_time.shape != other_type.shape: + raise ValueError( + "other_time must have the same shape as other_type, got " + f"{tuple(other_time.shape)} vs {tuple(other_type.shape)}" + ) + other_time = other_time.to(device=event_seq.device, dtype=time_seq.dtype) + h_other, other_mask = self.tokenizer( + other_type=other_type, + other_value=other_value, + other_value_kind=other_value_kind, + ) + h_other = h_other.to(device=event_seq.device) + other_mask = other_mask.to(device=event_seq.device, dtype=torch.bool) + + h_disease = torch.cat([h_disease, h_other], dim=1) + t_disease = torch.cat([t_disease, other_time], dim=1) + padding_mask = torch.cat([padding_mask, other_mask], dim=1) + h_disease = h_disease * padding_mask.unsqueeze(-1).to(h_disease.dtype) + + if mode == "all_future": + batch_size = event_seq.size(0) + query = self.query_token.view(1, 1, -1).expand(batch_size, 1, -1) + h_disease = torch.cat([h_disease, query], dim=1) + t_disease = torch.cat([t_disease, t_query[:, None]], dim=1) + query_mask = torch.ones( + batch_size, + 1, + dtype=torch.bool, + device=event_seq.device, + ) + padding_mask = torch.cat([padding_mask, query_mask], dim=1) + + sex_emb = self.gender_embedding(sex)[:, None, :] + h_disease = h_disease + sex_emb + h_disease = h_disease * padding_mask.unsqueeze(-1).to(h_disease.dtype) + + rope_cache = None + rbf_cache = None + if self.time_mode == "absolute": + h_disease = h_disease + self.age_encoding(t_disease) + h_disease = h_disease * padding_mask.unsqueeze(-1).to(h_disease.dtype) + elif self.time_mode == "relative": + rope_cache = self.rope.precompute_cache(t_disease) + rbf_cache = self.rbf.precompute_cache(t_disease) + + attn_mask = self._make_history_attn_mask( + padding_mask=padding_mask, + time_seq=t_disease, + dtype=h_disease.dtype, + ) + for block in self.blocks: + h_disease = block( + h_disease, + rope_cache=rope_cache, + rbf_cache=rbf_cache, + attn_mask=attn_mask, + ) + h_disease = h_disease * padding_mask.unsqueeze(-1).to(h_disease.dtype) + + h_disease = self.final_ln(h_disease) + h_disease = h_disease * padding_mask.unsqueeze(-1).to(h_disease.dtype) + + if mode == "all_future": + hidden = h_disease[:, -1, :] + if return_output: + return DeepHealthOutput( + hidden=hidden, + time_seq=t_query[:, None], + padding_mask=torch.ones( + hidden.size(0), + 1, + dtype=torch.bool, + device=hidden.device, + ), + event_len=event_len, + ) + return hidden + if return_output: + h_event = h_disease[:, :event_len, :] + t_event = t_disease[:, :event_len] + event_mask = padding_mask[:, :event_len] + h_extra, t_extra, extra_mask = self._pool_other_by_time( + h_other=h_disease[:, event_len:, :], + other_time=t_disease[:, event_len:], + other_mask=padding_mask[:, event_len:], + ) + return DeepHealthOutput( + hidden=torch.cat([h_event, h_extra], dim=1), + time_seq=torch.cat([t_event, t_extra], dim=1), + padding_mask=torch.cat([event_mask, extra_mask], dim=1), + event_len=event_len, + ) + return h_disease[:, :event_len, :] + + def forward_next_token(self, **kwargs) -> torch.Tensor: + return self._forward_shared(mode="next_token", **kwargs) + + def forward_all_future(self, **kwargs) -> torch.Tensor: + return self._forward_shared(mode="all_future", **kwargs) + + def forward(self, target_mode: str | None = None, **kwargs) -> torch.Tensor: + mode = self.target_mode if target_mode is None else target_mode + return self._forward_shared(mode=mode, **kwargs) + + def calc_risk(self, x: torch.Tensor) -> torch.Tensor: + return self.risk_head(x) + + def calc_weibull_rho(self, x: torch.Tensor) -> torch.Tensor: + if self.dist_mode != "weibull": + raise RuntimeError( + f"calc_weibull_rho called with dist_mode={self.dist_mode!r}" + ) + return F.softplus(self.rho_head(x)) + 1e-6 + + def calc_death_rho(self, x: torch.Tensor) -> torch.Tensor: + if self.dist_mode != "mixed": + raise RuntimeError( + f"calc_death_rho called with dist_mode={self.dist_mode!r}" + ) + return F.softplus(self.rho_death_head(x)).squeeze(-1) + 1e-6 diff --git a/prepare_data.py b/prepare_data.py new file mode 100644 index 0000000..2838a70 --- /dev/null +++ b/prepare_data.py @@ -0,0 +1,385 @@ +"""ETL pipeline for UK Biobank data preparation. + +This script converts raw UK Biobank CSV exports into the artefacts consumed by +DeepHealth: + +* ``ukb_event_data.npy``: ``(N, 3)`` uint32 array of ``(eid, days, label)`` + disease/death/checkup events sorted by patient then time. +* ``ukb_basic_info.csv``: basic patient table indexed by ``eid`` with ``sex``. +* ``ukb_other_info.npy``: ``(M, 5)`` float64 array of + ``(eid, type, value, value_kind, time)`` rows. ``type=0`` is reserved for + padding, ``value_kind=1`` means continuous, and ``value_kind=2`` means + categorical. +* ``cate_types.csv``: categorical-variable metadata with + ``type,name,n_categories``. Dataset code computes global category ids after + experiment-specific variable selection. + +Processing steps +---------------- +1. Stream the raw CSV in 10 000-row chunks to bound memory usage. +2. Convert date columns to integer day offsets from date of birth. +3. Extract ICD-10 date fields and cancer date/type fields into long-form + events and map codes to integer labels via ``labels.csv``. +4. De-duplicate events per ``(eid, label)`` keeping the earliest occurrence. +5. Convert available non-sex tabular fields into unified other-information + tokens timestamped by ``date_of_assessment``. +6. Write event data, sex, unified other-information tokens, and categorical + type metadata. + +Usage +----- +:: + + python prepare_data.py + +The script expects these files in the working directory: + +* ``ukb_data.csv``: raw UK Biobank CSV export. +* ``field_ids_enriched.csv``: field-ID to column-name mapping. +* ``icd10_codes_mod.tsv``: ICD-10 field to date-column mapping. +* ``labels.csv``: disease-code to integer-label mapping. +""" + +import numpy as np # Numerical operations +import pandas as pd # Pandas for data manipulation +import tqdm # Progress bar for chunk processing + + +CONT_VALUE_KIND = 1 +CATE_VALUE_KIND = 2 + + +def _sort_values(values): + """Sort mixed pandas/numpy scalar values deterministically.""" + try: + return sorted(values) + except TypeError: + return sorted(values, key=lambda x: str(x)) + + +def _build_other_info_tokens( + table: pd.DataFrame, + feature_fields: list[str], + *, + time_col: str = "date_of_assessment", +) -> tuple[np.ndarray, pd.DataFrame]: + """Convert wide tabular features into (eid, type, value, kind, time) rows.""" + rows = [] + cate_meta = [] + present_features = [ + col for col in feature_fields + if col in table.columns and col not in {time_col, "sex"} + ] + + if time_col not in table.columns: + raise ValueError( + f"{time_col!r} is required to timestamp other-information tokens" + ) + + token_times = pd.to_numeric(table[time_col], errors="coerce") + + for type_idx, col in enumerate(present_features, start=1): + series = table[col] + n_unique = series.dropna().nunique() + valid_time = token_times.notna() + + if n_unique > 10: + numeric = pd.to_numeric(series, errors="coerce") + valid = numeric.notna() & valid_time + if not valid.any(): + continue + rows.append( + np.column_stack( + ( + table.index[valid].to_numpy(dtype=np.float64), + np.full(valid.sum(), type_idx, dtype=np.float64), + numeric[valid].to_numpy(dtype=np.float64), + np.full(valid.sum(), CONT_VALUE_KIND, dtype=np.float64), + token_times[valid].to_numpy(dtype=np.float64), + ) + ) + ) + else: + unique_vals = _sort_values(series.dropna().unique()) + value_map = {val: idx + 1 for idx, val in enumerate(unique_vals)} + mapped = series.map(value_map) + valid = mapped.notna() & valid_time + n_categories = len(unique_vals) + cate_meta.append( + { + "type": type_idx, + "name": col, + "n_categories": n_categories, + } + ) + if not valid.any(): + continue + rows.append( + np.column_stack( + ( + table.index[valid].to_numpy(dtype=np.float64), + np.full(valid.sum(), type_idx, dtype=np.float64), + mapped[valid].to_numpy(dtype=np.float64), + np.full(valid.sum(), CATE_VALUE_KIND, dtype=np.float64), + token_times[valid].to_numpy(dtype=np.float64), + ) + ) + ) + + cate_types = pd.DataFrame( + cate_meta, + columns=["type", "name", "n_categories"], + ) + if not rows: + return np.empty((0, 5), dtype=np.float64), cate_types + out = np.vstack(rows) + return out[np.lexsort((out[:, 3], out[:, 1], out[:, 0]))], cate_types + + +def _unique_preserve_order(values): + """Return unique values while preserving first-seen order.""" + seen = set() + out = [] + for value in values: + if value not in seen: + seen.add(value) + out.append(value) + return out + + +# CSV mapping field IDs to human-readable names +field_map_file = "field_ids_enriched.csv" + +field_df = pd.read_csv(field_map_file, low_memory=False) +required_cols = {"field_instance", "var_name", "field_type"} +missing_cols = required_cols - set(field_df.columns) +if missing_cols: + raise ValueError( + f"{field_map_file} is missing required columns: {sorted(missing_cols)}" + ) + +field_df = field_df.dropna(subset=["field_instance", "var_name", "field_type"]) +field_df["field_instance"] = field_df["field_instance"].astype(str) +field_df["var_name"] = field_df["var_name"].astype(str) +field_df["field_type"] = field_df["field_type"].astype(int) + +# Map original field ID -> renamed output variable. +field_dict = dict(zip(field_df["field_instance"], field_df["var_name"])) + +# Build source field groups from field_type. +basic_info_fields = _unique_preserve_order( + field_df.loc[field_df["field_type"] == 0, "var_name"].tolist() +) +assessment_fields = _unique_preserve_order( + field_df.loc[field_df["field_type"] == 1, "var_name"].tolist() +) +exposure_fields = _unique_preserve_order( + field_df.loc[field_df["field_type"] == 2, "var_name"].tolist() +) + +# Keep only sex and enrollment time for the basic info table. +basic_info_fields = [ + f for f in ["sex", "date_of_assessment"] if f in set(basic_info_fields) +] + +# Fields needed for tabular extraction from raw CSV. +tabular_fields = _unique_preserve_order( + basic_info_fields + assessment_fields + exposure_fields +) + +# TSV mapping field IDs to ICD10-related date columns +field_to_icd_map = "icd10_codes_mod.tsv" +# Date-like variables to be converted to offsets +date_vars = [] +with open(field_to_icd_map, encoding="utf-8") as f: # Open ICD10 mapping + for line in f: # Iterate each mapping row + parts = line.strip().split() # Split on whitespace for TSV + if len(parts) >= 6: # Guard against malformed lines + # Map field ID to the date column name + field_dict[parts[0]] = parts[5] + date_vars.append(parts[5]) # Track date column names in order + +for j in range(17): # Map up to 17 cancer entry slots (dates and types) + # Cancer diagnosis date slot j + field_dict[f"40005-{j}.0"] = f"cancer_date_{j}" + field_dict[f"40006-{j}.0"] = f"cancer_type_{j}" # Cancer type/code slot j + +# Number of ICD-related date columns before adding extras +len_icd = len(date_vars) +date_vars.extend( + ["Death", "date_of_assessment"] # Add outcome date and assessment date + + + # Add cancer date columns + [f"cancer_date_{j}" for j in range(17)] +) + +labels_file = "labels.csv" # File listing label codes +label_dict = {} # Map code string -> integer label id +with open(labels_file, encoding="utf-8") as f: # Open labels file + for idx, line in enumerate(f): # Enumerate to assign incremental label IDs + parts = line.strip().split(" ") # Split by space + if parts and parts[0]: # Guard against empty lines + # Start labels from 1 to reserve 0 for padding, 1 for checkup + label_dict[parts[0]] = idx + 2 + +# Pre-build lookup: ICD/Death column name -> integer label for fast per-column extraction +icd_label_lookup = {} +for col_name in date_vars[:len_icd]: + if col_name in label_dict: + icd_label_lookup[col_name] = label_dict[col_name] +if "Death" in label_dict: + icd_label_lookup["Death"] = label_dict["Death"] + +event_list = [] # Accumulator for event arrays across chunks +tabular_list = [] # Accumulator for tabular feature DataFrames across chunks +ukb_iterator = pd.read_csv( # Stream UK Biobank data in chunks + "ukb_data.csv", + sep=",", + chunksize=10000, # Stream file in manageable chunks to reduce memory footprint + # First column (participant ID) becomes DataFrame index + index_col=0, + low_memory=False, # Disable type inference optimization for consistent dtypes +) +# Iterate chunks with progress +for ukb_chunk in tqdm.tqdm(ukb_iterator, desc="Processing UK Biobank data"): + # Rename columns to friendly names + ukb_chunk = ukb_chunk.rename(columns=field_dict) + # Require sex to be present + ukb_chunk.dropna(subset=["sex"], inplace=True) + if ukb_chunk.empty: + continue + + # Construct date of birth from year and month (day fixed to 1) + dob = pd.to_datetime( + pd.DataFrame( + {"year": ukb_chunk["year"], "month": ukb_chunk["month"], "day": 1} + ), + errors="coerce", + ) + + # Use only date variables that actually exist in the current chunk + present_date_vars = [c for c in date_vars if c in ukb_chunk.columns] + + # Convert date-like columns to day offsets from dob (per-column, avoids .apply overhead) + for col in present_date_vars: + ukb_chunk[col] = ( + pd.to_datetime( + ukb_chunk[col], format="%Y-%m-%d", errors="coerce") - dob + ).dt.days + + # Append tabular features (use only columns that exist) + present_tabular_fields = [ + c for c in tabular_fields if c in ukb_chunk.columns] + tabular_list.append(ukb_chunk[present_tabular_fields].copy()) + + # Extract ICD10 + Death events directly per column (avoids costly melt) + icd10_cols = present_date_vars[: len_icd + 1] + for col in icd10_cols: + if col not in icd_label_lookup: + continue + label_id = icd_label_lookup[col] + series = ukb_chunk[col] + valid_mask = series.notna() + if not valid_mask.any(): + continue + event_list.append( + np.column_stack( + ( + ukb_chunk.index[valid_mask].values, + series[valid_mask].values.astype(np.int64), + np.full(valid_mask.sum(), label_id, dtype=np.int64), + ) + ) + ) + + # Optimized cancer processing without wide_to_long + cancer_frames = [] + for j in range(17): + d_col = f"cancer_date_{j}" + t_col = f"cancer_type_{j}" + if d_col in ukb_chunk.columns and t_col in ukb_chunk.columns: + # Filter rows where both date and type are present + mask = ukb_chunk[d_col].notna() & ukb_chunk[t_col].notna() + if mask.any(): + subset_idx = ukb_chunk.index[mask] + subset_days = ukb_chunk.loc[mask, d_col] + subset_type = ukb_chunk.loc[mask, t_col] + + # Map cancer type to label + # Use first 3 chars + cancer_codes = subset_type.str.slice(0, 3) + labels = cancer_codes.map(label_dict) + + # Filter valid labels + valid_label_mask = labels.notna() + if valid_label_mask.any(): + # Create array: eid, days, label + # Ensure types are correct for numpy + c_eids = subset_idx[valid_label_mask].values + c_days = subset_days[valid_label_mask].values + c_labels = labels[valid_label_mask].values + + # Stack + chunk_cancer_data = np.column_stack( + (c_eids, c_days, c_labels)) + cancer_frames.append(chunk_cancer_data) + + if cancer_frames: + event_list.append(np.vstack(cancer_frames)) + + # Add checkup events with label=1 using date_of_assessment (already in days from dob) + if "date_of_assessment" in ukb_chunk.columns: + doa_series = ukb_chunk["date_of_assessment"].dropna() + if not doa_series.empty: + checkup_data = np.column_stack( + ( + doa_series.index.values, + doa_series.values.astype(int), + np.ones(len(doa_series), dtype=int), + ) + ) + event_list.append(checkup_data) + +# Combine tabular chunks +final_tabular = pd.concat(tabular_list, axis=0, ignore_index=False) +final_tabular.index.name = "eid" # Ensure index named consistently +data = np.vstack(event_list) # Stack all event arrays into one + +# Sort by participant then day +data = data[np.lexsort((data[:, 1], data[:, 0]))] + +# Keep only events with non-negative day offsets +data = data[data[:, 1] >= 0] + +# Remove duplicate (participant_id, label) pairs keeping first occurrence (numpy-based). +_, first_idx = np.unique(data[:, [0, 2]], axis=0, return_index=True) +first_idx.sort() # Preserve original sorted order +data = data[first_idx] + +# Store compactly using unsigned 32-bit integers +data = data.astype(np.uint32) + +# Select eid in both data and tabular +valid_eids = np.intersect1d(data[:, 0], final_tabular.index) +data = data[np.isin(data[:, 0], valid_eids)] +final_tabular = final_tabular.loc[valid_eids] +final_tabular = final_tabular.convert_dtypes() + +# Save basic sex information separately. +basic_info = final_tabular[["sex"]].copy() +basic_info.to_csv("ukb_basic_info.csv") + +# Save unified other-information tokens. Missing values simply produce no token. +other_info_fields = _unique_preserve_order( + basic_info_fields + assessment_fields + exposure_fields +) +other_info, cate_types = _build_other_info_tokens( + final_tabular, + other_info_fields, + time_col="date_of_assessment", +) +np.save("ukb_other_info.npy", other_info) +cate_types.to_csv("cate_types.csv", index=False) + +# Save event data +np.save("ukb_event_data.npy", data) diff --git a/prepare_event_dates.py b/prepare_event_dates.py new file mode 100644 index 0000000..4d84ad3 --- /dev/null +++ b/prepare_event_dates.py @@ -0,0 +1,203 @@ +"""Create a compact calendar-dated disease-event index from ``ukb_data.csv``. + +Unlike ``prepare_data.py``, this ETL does not create model-ready relative-time +sequences or other-information tokens. It writes one structured ``.npy`` file +with exactly three fields: + + eid int64 + event_date datetime64[D] + token int32 + +``token`` follows the existing ``labels.csv`` convention used by +``prepare_data.py``: padding=0, checkup=1 (not emitted here), and the first +label in ``labels.csv`` receives token 2. Each ``(eid, token)`` is deduplicated +to the first known event date. + +The output is intended for calendar-indexed temperature and air-pollution +queries. It contains no date of birth, sex, covariates, or checkup events. + +Usage +----- +python prepare_event_dates.py --output ukb_disease_event_dates.npy +""" + +from __future__ import annotations + +import argparse +from pathlib import Path + +import numpy as np +import pandas as pd +try: + from tqdm import tqdm +except ImportError: # Keep the ETL runnable in minimal Python environments. + tqdm = None + + +EVENT_DTYPE = np.dtype( + [ + ("eid", " dict[str, int]: + """Return the label-code -> token mapping shared with ``prepare_data.py``.""" + token_map: dict[str, int] = {} + with Path(labels_file).open(encoding="utf-8") as handle: + for index, line in enumerate(handle): + code = line.strip().split(" ", maxsplit=1)[0] + if code: + token_map[code] = index + 2 + return token_map + + +def build_raw_column_map( + field_map_file: str | Path, + icd_map_file: str | Path, +) -> tuple[dict[str, str], list[str]]: + """Build raw-column renames and the calendar-date event columns to inspect.""" + field_df = pd.read_csv(field_map_file, low_memory=False) + required = {"field_instance", "var_name"} + missing = required - set(field_df.columns) + if missing: + raise ValueError(f"{field_map_file} is missing columns: {sorted(missing)}") + + raw_to_name = dict( + zip(field_df["field_instance"].astype(str), field_df["var_name"].astype(str)) + ) + icd_date_columns: list[str] = [] + with Path(icd_map_file).open(encoding="utf-8") as handle: + for line in handle: + parts = line.strip().split() + if len(parts) >= 6: + raw_to_name[parts[0]] = parts[5] + icd_date_columns.append(parts[5]) + + for slot in range(17): + raw_to_name[f"40005-{slot}.0"] = f"cancer_date_{slot}" + raw_to_name[f"40006-{slot}.0"] = f"cancer_type_{slot}" + return raw_to_name, icd_date_columns + + +def _records_from_icd_columns( + chunk: pd.DataFrame, + event_columns: list[str], + token_map: dict[str, int], +) -> list[pd.DataFrame]: + frames: list[pd.DataFrame] = [] + for column in event_columns: + token = token_map.get(column) + if token is None or column not in chunk.columns: + continue + event_date = pd.to_datetime(chunk[column], format="%Y-%m-%d", errors="coerce") + valid = event_date.notna() + if valid.any(): + frames.append( + pd.DataFrame( + { + "eid": chunk.index[valid].astype("int64"), + "event_date": event_date.loc[valid].to_numpy(), + "token": np.full(valid.sum(), token, dtype=np.int32), + } + ) + ) + return frames + + +def _records_from_cancer_columns(chunk: pd.DataFrame, token_map: dict[str, int]) -> list[pd.DataFrame]: + frames: list[pd.DataFrame] = [] + for slot in range(17): + date_column = f"cancer_date_{slot}" + type_column = f"cancer_type_{slot}" + if date_column not in chunk.columns or type_column not in chunk.columns: + continue + event_date = pd.to_datetime(chunk[date_column], format="%Y-%m-%d", errors="coerce") + code = chunk[type_column].astype("string").str.slice(0, 3) + token = code.map(token_map) + valid = event_date.notna() & token.notna() + if valid.any(): + frames.append( + pd.DataFrame( + { + "eid": chunk.index[valid].astype("int64"), + "event_date": event_date.loc[valid].to_numpy(), + "token": token.loc[valid].astype("int32").to_numpy(), + } + ) + ) + return frames + + +def prepare_event_dates( + *, + ukb_data_file: str | Path, + field_map_file: str | Path, + icd_map_file: str | Path, + labels_file: str | Path, + output_file: str | Path, + chunksize: int = 10_000, +) -> int: + """Stream the raw UKB export, then write a sorted structured event array.""" + token_map = load_label_tokens(labels_file) + raw_to_name, icd_date_columns = build_raw_column_map(field_map_file, icd_map_file) + event_columns = [*icd_date_columns, "Death"] + frames: list[pd.DataFrame] = [] + + reader = pd.read_csv( + ukb_data_file, + chunksize=chunksize, + index_col=0, # UKB participant ID / eid + low_memory=False, + ) + chunk_iterator = tqdm(reader, desc="Extracting calendar-dated disease events") if tqdm else reader + for raw_chunk in chunk_iterator: + chunk = raw_chunk.rename(columns=raw_to_name) + frames.extend(_records_from_icd_columns(chunk, event_columns, token_map)) + frames.extend(_records_from_cancer_columns(chunk, token_map)) + + if not frames: + result = np.empty(0, dtype=EVENT_DTYPE) + else: + events = pd.concat(frames, ignore_index=True) + events = events.dropna(subset=["eid", "event_date", "token"]) + events = events.sort_values(["eid", "token", "event_date"], kind="stable") + # Match prepare_data.py: first occurrence of each disease/death token. + events = events.drop_duplicates(["eid", "token"], keep="first") + events = events.sort_values(["eid", "event_date", "token"], kind="stable") + + result = np.empty(len(events), dtype=EVENT_DTYPE) + result["eid"] = events["eid"].to_numpy(dtype=np.int64) + result["event_date"] = events["event_date"].to_numpy(dtype="datetime64[D]") + result["token"] = events["token"].to_numpy(dtype=np.int32) + + np.save(output_file, result) + return len(result) + + +def main() -> None: + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("--ukb-data", default="ukb_data.csv") + parser.add_argument("--field-map", default="field_ids_enriched.csv") + parser.add_argument("--icd-map", default="icd10_codes_mod.tsv") + parser.add_argument("--labels", default="labels.csv") + parser.add_argument("--output", default="ukb_disease_event_dates.npy") + parser.add_argument("--chunksize", type=int, default=10_000) + args = parser.parse_args() + if args.chunksize <= 0: + raise ValueError("chunksize must be positive") + count = prepare_event_dates( + ukb_data_file=args.ukb_data, + field_map_file=args.field_map, + icd_map_file=args.icd_map, + labels_file=args.labels, + output_file=args.output, + chunksize=args.chunksize, + ) + print(f"Wrote {count:,} first disease/death events to {args.output}") + + +if __name__ == "__main__": + main() diff --git a/readouts.py b/readouts.py new file mode 100644 index 0000000..b36285c --- /dev/null +++ b/readouts.py @@ -0,0 +1,107 @@ +from __future__ import annotations + +from dataclasses import dataclass + +import torch +import torch.nn as nn + + +@dataclass +class ReadoutOutput: + hidden: torch.Tensor + readout_mask: torch.Tensor + + +class TokenReadout(nn.Module): + def forward( + self, + hidden: torch.Tensor, + time_seq: torch.Tensor, + padding_mask: torch.Tensor, + readout_mask: torch.Tensor | None = None, + ) -> ReadoutOutput: + mask = padding_mask if readout_mask is None else readout_mask + return ReadoutOutput(hidden=hidden, readout_mask=mask.bool()) + + +class SameTimeGroupEndReadout(nn.Module): + def __init__(self, reduce: str = "mean"): + super().__init__() + if reduce not in {"mean", "sum"}: + raise ValueError("reduce must be either 'mean' or 'sum'") + self.reduce = reduce + + def forward( + self, + hidden: torch.Tensor, + time_seq: torch.Tensor, + padding_mask: torch.Tensor, + readout_mask: torch.Tensor | None = None, + ) -> ReadoutOutput: + if readout_mask is None: + next_is_new_time = torch.ones_like(padding_mask, dtype=torch.bool) + next_is_new_time[:, :-1] = time_seq[:, 1:] != time_seq[:, :-1] + readout_mask = padding_mask.bool() & next_is_new_time + else: + readout_mask = readout_mask.bool() + + group_start = torch.ones_like(padding_mask, dtype=torch.bool) + group_start[:, 1:] = time_seq[:, 1:] != time_seq[:, :-1] + group_start = group_start & padding_mask.bool() + + group_id = group_start.long().cumsum(dim=1) - 1 + group_id = group_id.clamp_min(0) + max_groups = hidden.size(1) + + group_sum = hidden.new_zeros(hidden.size(0), max_groups, hidden.size(2)) + group_sum.scatter_add_( + 1, + group_id.unsqueeze(-1).expand_as(hidden), + hidden * padding_mask.unsqueeze(-1).to(hidden.dtype), + ) + + if self.reduce == "mean": + group_count = hidden.new_zeros(hidden.size(0), max_groups, 1) + group_count.scatter_add_( + 1, + group_id.unsqueeze(-1), + padding_mask.unsqueeze(-1).to(hidden.dtype), + ) + group_sum = group_sum / group_count.clamp_min(1.0) + + out = hidden.clone() + out[readout_mask] = group_sum.gather( + 1, + group_id.unsqueeze(-1).expand_as(hidden), + )[readout_mask] + return ReadoutOutput(hidden=out, readout_mask=readout_mask) + + +class LastValidReadout(nn.Module): + def forward( + self, + hidden: torch.Tensor, + time_seq: torch.Tensor, + padding_mask: torch.Tensor, + readout_mask: torch.Tensor | None = None, + ) -> ReadoutOutput: + batch_size, seq_len = padding_mask.shape + last_idx = padding_mask.long().sum(dim=1).clamp_min(1) - 1 + out = hidden[torch.arange(batch_size, device=hidden.device), last_idx] + mask = torch.ones(batch_size, dtype=torch.bool, device=hidden.device) + return ReadoutOutput(hidden=out, readout_mask=mask) + + +def build_readout(name: str, **kwargs) -> nn.Module: + name = name.lower() + if name == "token": + return TokenReadout() + if name in {"same_time_group_end", "same_time"}: + return SameTimeGroupEndReadout(**kwargs) + if name == "last_valid": + return LastValidReadout() + raise ValueError( + "Unknown readout {!r}. Available: token, same_time_group_end, last_valid.".format( + name + ) + ) diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..a4871bd --- /dev/null +++ b/requirements.txt @@ -0,0 +1,5 @@ +numpy +pandas +torch +tqdm +scikit-learn diff --git a/targets.py b/targets.py new file mode 100644 index 0000000..f64de6a --- /dev/null +++ b/targets.py @@ -0,0 +1,394 @@ +# targets.py +from __future__ import annotations + +from dataclasses import dataclass +from typing import Iterable + +import numpy as np + + +PAD_IDX = 0 +CHECKUP_IDX = 1 +NO_EVENT_IDX = 2 +DAYS_PER_YEAR = 365.25 + + +@dataclass(frozen=True) +class NextTokenTargets: + """ + Delphi2M-style next-token supervision targets. + + Shapes: + input_events: (L,) + input_times_years: (L,) + target_events: (L,) + target_times_years:(L,) + + where L = N - 1. + """ + input_events: np.ndarray + input_times_years: np.ndarray + target_events: np.ndarray + target_times_years: np.ndarray + + +@dataclass(frozen=True) +class UniqueTimeSetTargets: + """ + Unique-time set supervision targets. + + Shapes: + readout_mask: (L,) + target_dt_unique: (L,) + target_multi_hot: (L, vocab_size) + + where L = N - 1. + + Only group-end positions can have readout_mask=True. + target_dt_unique is measured in years. + """ + readout_mask: np.ndarray + target_dt_unique: np.ndarray + target_multi_hot: np.ndarray + + +@dataclass(frozen=True) +class TargetPack: + """ + Combined target package for one patient sequence. + + Contains both next-token targets and unique-time-set targets. + The training pipeline decides which one to use. + """ + next_token: NextTokenTargets + unique_time_set: UniqueTimeSetTargets + + +def _as_numpy_1d( + x: np.ndarray, + name: str, + dtype: np.dtype | type | None = None, +) -> np.ndarray: + arr = np.asarray(x) + if arr.ndim != 1: + raise ValueError(f"{name} must be 1D, got shape {arr.shape}") + if dtype is not None: + arr = arr.astype(dtype) + return arr + + +def validate_event_sequence( + labels: np.ndarray, + times_days: np.ndarray, + *, + require_sorted: bool = True, +) -> None: + """ + Validate one patient's event sequence. + + labels: + 1D integer label ids. + + times_days: + 1D event times in days. + + require_sorted: + If True, raises when times_days is not non-decreasing. + """ + labels = _as_numpy_1d(labels, "labels") + times_days = _as_numpy_1d(times_days, "times_days") + + if len(labels) != len(times_days): + raise ValueError( + f"labels and times_days must have the same length, " + f"got {len(labels)} and {len(times_days)}" + ) + + if len(labels) == 0: + raise ValueError("Empty event sequence is not valid.") + + if np.any(labels < 0): + raise ValueError("labels contains negative ids.") + + if not np.all(np.isfinite(times_days)): + raise ValueError("times_days contains non-finite values.") + + if require_sorted and len(times_days) > 1: + if np.any(np.diff(times_days) < 0): + raise ValueError("times_days must be non-decreasing.") + + +def build_next_token_targets( + labels: np.ndarray, + times_days: np.ndarray, + *, + require_sorted: bool = True, +) -> NextTokenTargets: + """ + Build Delphi2M-style autoregressive next-token targets. + + Given full sequence: + + labels: [x0, x1, x2, ..., xN-1] + times_days: [t0, t1, t2, ..., tN-1] + + returns: + + input_events: [x0, x1, ..., xN-2] + input_times_years: [t0, t1, ..., tN-2] / 365.25 + target_events: [x1, x2, ..., xN-1] + target_times_years: [t1, t2, ..., tN-1] / 365.25 + + This function does not ignore PAD/CHECKUP/NO_EVENT. Ignoring belongs to + the loss function because different objectives may use different ignore ids. + """ + labels = _as_numpy_1d(labels, "labels", np.int64) + times_days = _as_numpy_1d(times_days, "times_days", np.float32) + validate_event_sequence(labels, times_days, require_sorted=require_sorted) + + if len(labels) < 2: + raise ValueError( + "Need at least two events to build next-token targets." + ) + + input_events = labels[:-1].astype(np.int64) + input_times_years = (times_days[:-1] / DAYS_PER_YEAR).astype(np.float32) + + target_events = labels[1:].astype(np.int64) + target_times_years = (times_days[1:] / DAYS_PER_YEAR).astype(np.float32) + + return NextTokenTargets( + input_events=input_events, + input_times_years=input_times_years, + target_events=target_events, + target_times_years=target_times_years, + ) + + +def build_unique_time_set_targets( + labels: np.ndarray, + times_days: np.ndarray, + *, + vocab_size: int, + ignored_target_ids: Iterable[int] = (PAD_IDX, CHECKUP_IDX), + require_sorted: bool = True, +) -> UniqueTimeSetTargets: + """ + Build next-unique-time set targets. + + This is the target construction used by your UTS / default mode. + + For each input position i: + - only if i is the last token of its timestamp group; + - find the next distinct timestamp group; + - target is the set of valid event labels at that next timestamp. + + Example: + + t=49: X + t=50: A, B, C + t=51: D, E + + Supervises: + + X@49 -> {A, B, C}@50 + group_end@50 -> {D, E}@51 + + It does NOT supervise: + + A@50 -> B@50 + B@50 -> C@50 + + Parameters + ---------- + labels: + Full event sequence labels, shape (N,). + + times_days: + Full event sequence times in days, shape (N,). + + vocab_size: + Size of output vocabulary. + + ignored_target_ids: + Label ids that should not enter target_multi_hot. + Usually: + no no-event: {0, 1} + with no-event: {0, 1, 2} + For UTS, I recommend ignoring unless explicitly testing it + as an event target. + + Returns + ------- + UniqueTimeSetTargets + """ + labels = _as_numpy_1d(labels, "labels", np.int64) + times_days = _as_numpy_1d(times_days, "times_days", np.float32) + validate_event_sequence(labels, times_days, require_sorted=require_sorted) + + if vocab_size <= 0: + raise ValueError(f"vocab_size must be positive, got {vocab_size}") + + if len(labels) < 2: + raise ValueError( + "Need at least two events to build unique-time-set targets." + ) + + input_len = len(labels) - 1 + + readout_mask = np.zeros(input_len, dtype=bool) + target_dt_unique = np.zeros(input_len, dtype=np.float32) + target_multi_hot = np.zeros((input_len, vocab_size), dtype=bool) + + ignored = {int(x) for x in ignored_target_ids} + + unique_times = np.unique(times_days) + time_to_group_idx = {t: i for i, t in enumerate(unique_times)} + group_indices = np.array([time_to_group_idx[t] + for t in times_days], dtype=np.int64) + + for i in range(input_len): + current_group = group_indices[i] + + is_last_in_group = ( + i == input_len - 1 + or group_indices[i + 1] != current_group + ) + if not is_last_in_group: + continue + + next_group_idx = current_group + 1 + if next_group_idx >= len(unique_times): + continue + + next_time = unique_times[next_group_idx] + next_labels = labels[group_indices == next_group_idx] + + valid_next_labels: list[int] = [] + for lab in next_labels: + lab_int = int(lab) + if lab_int in ignored: + continue + if lab_int < 0 or lab_int >= vocab_size: + continue + valid_next_labels.append(lab_int) + + # If next timestamp contains only technical tokens, do not supervise UTS. + if len(valid_next_labels) == 0: + continue + + readout_mask[i] = True + target_dt_unique[i] = float(next_time - times_days[i]) / DAYS_PER_YEAR + target_multi_hot[i, valid_next_labels] = True + + return UniqueTimeSetTargets( + readout_mask=readout_mask, + target_dt_unique=target_dt_unique.astype(np.float32), + target_multi_hot=target_multi_hot, + ) + + +def build_all_targets( + labels: np.ndarray, + times_days: np.ndarray, + *, + vocab_size: int, + ignored_uts_target_ids: Iterable[int] = (PAD_IDX, CHECKUP_IDX), + require_sorted: bool = True, +) -> TargetPack: + """ + Build both next-token targets and unique-time-set targets for one patient. + + This is the function dataset.py should usually call during initialization. + + The dataset can then store: + event_seq = target_pack.next_token.input_events + time_seq = target_pack.next_token.input_times_years + + target_event_seq = target_pack.next_token.target_events + target_time_seq = target_pack.next_token.target_times_years + + readout_mask = target_pack.unique_time_set.readout_mask + target_dt_unique = target_pack.unique_time_set.target_dt_unique + target_multi_hot = target_pack.unique_time_set.target_multi_hot + """ + next_token = build_next_token_targets( + labels=labels, + times_days=times_days, + require_sorted=require_sorted, + ) + + unique_time_set = build_unique_time_set_targets( + labels=labels, + times_days=times_days, + vocab_size=vocab_size, + ignored_target_ids=ignored_uts_target_ids, + require_sorted=require_sorted, + ) + + return TargetPack( + next_token=next_token, + unique_time_set=unique_time_set, + ) + + +def get_group_end_mask_from_times( + times_days: np.ndarray, + *, + input_len: int | None = None, +) -> np.ndarray: + """ + Convenience utility for debugging. + + Returns a bool mask indicating the last token of each same-time group + within the input sequence. + + If input_len is None, uses len(times_days) - 1, matching model input length. + """ + times_days = _as_numpy_1d(times_days, "times_days", np.float32) + + if input_len is None: + input_len = len(times_days) - 1 + + if input_len < 0 or input_len > len(times_days): + raise ValueError( + f"Invalid input_len={input_len} for sequence length {len(times_days)}" + ) + + out = np.zeros(input_len, dtype=bool) + + for i in range(input_len): + is_last_in_group = ( + i == input_len - 1 + or times_days[i + 1] != times_days[i] + ) + out[i] = is_last_in_group + + return out + + +def summarize_targets( + target_pack: TargetPack, +) -> dict[str, int | float]: + """ + Small debugging helper for logging. + """ + nt = target_pack.next_token + uts = target_pack.unique_time_set + + n_tokens = int(len(nt.input_events)) + n_readout = int(uts.readout_mask.sum()) + n_positive_labels = int(uts.target_multi_hot.sum()) + + mean_set_size = ( + float(n_positive_labels / n_readout) + if n_readout > 0 + else 0.0 + ) + + return { + "n_input_tokens": n_tokens, + "n_uts_readouts": n_readout, + "n_uts_positive_labels": n_positive_labels, + "mean_uts_set_size": mean_set_size, + } diff --git a/train_next_step.py b/train_next_step.py new file mode 100644 index 0000000..35f86ff --- /dev/null +++ b/train_next_step.py @@ -0,0 +1,667 @@ +""" +Train DeepHealth with next-token / next-time-point supervision. + +The next-step dataset uses observed event histories, including CHECKUP state +tokens, plus optional gap imputation. UTS training reads out only +same-time group ends. +""" +from __future__ import annotations + +import argparse +import json +import logging +import math +import time +from pathlib import Path +from typing import Any, Dict + +import numpy as np +import torch +from torch.nn.utils import clip_grad_norm_ +from torch.optim import AdamW +from torch.utils.data import DataLoader, RandomSampler +from tqdm.auto import tqdm + +from dataset import HealthDataset, collate_fn +from losses import build_loss +from models import DeepHealth, DeepHealthOutput +from readouts import build_readout +from targets import CHECKUP_IDX, NO_EVENT_IDX, PAD_IDX +from train_util import ( + configure_torch_for_training, + create_unique_run_dir, + format_extra_info_types, + load_extra_info_types_file, + resolve_device, + save_checkpoint, + save_config, + set_optimizer_lr, + set_seed, + setup_logging, + split_dataset, + split_dataset_by_eid_files, +) + + +MODEL_INPUT_KEYS = ( + "event_seq", + "time_seq", + "sex", + "padding_mask", + "other_type", + "other_value", + "other_value_kind", + "other_time", +) + + +def parse_args() -> argparse.Namespace: + parser = argparse.ArgumentParser( + description="Train DeepHealth with next-token/point supervision") + + parser.add_argument("--data_prefix", type=str, default="ukb") + parser.add_argument("--labels_file", type=str, default="labels.csv") + parser.add_argument("--seed", type=int, default=42) + parser.add_argument("--extra_info_types_file", type=str, default=None) + parser.add_argument("--no_event_interval_years", type=float, default=5.0) + parser.add_argument("--include_no_event_in_uts_target", action="store_true") + + parser.add_argument("--train_ratio", type=float, default=0.7) + parser.add_argument("--val_ratio", type=float, default=0.15) + parser.add_argument("--test_ratio", type=float, default=0.15) + parser.add_argument("--train_eid_file", type=str, default="ukb_train_eid.csv") + parser.add_argument("--val_eid_file", type=str, default="ukb_val_eid.csv") + parser.add_argument("--test_eid_file", type=str, default="ukb_test_eid.csv") + + parser.add_argument("--n_embd", type=int, default=120) + parser.add_argument("--n_head", type=int, default=10) + parser.add_argument("--n_hist_layer", type=int, default=12) + parser.add_argument("--n_tab_layer", type=int, default=4) + parser.add_argument("--n_bins", type=int, default=16) + parser.add_argument("--extra_pool_reduce", type=str, default="mean", + choices=["mean", "sum"]) + parser.add_argument("--time_mode", type=str, default="relative", + choices=["relative", "absolute"]) + parser.add_argument("--dropout", type=float, default=0.0) + + parser.add_argument("--target_mode", type=str, default="uts", + choices=["delphi2m", "uts"]) + parser.add_argument("--readout_name", type=str, default=None, + choices=["token", "same_time_group_end", "last_valid"]) + parser.add_argument("--readout_reduce", type=str, default="mean", + choices=["mean", "sum"]) + parser.add_argument("--t_min", type=float, default=0.0027378507871321013) + parser.add_argument("--max_exp_input", type=float, default=60.0) + parser.add_argument("--ce_weight", type=float, default=1.0) + parser.add_argument("--time_weight", type=float, default=1.0) + parser.add_argument("--ignore_no_event_in_delphi2m", action="store_true") + + parser.add_argument("--batch_size", type=int, default=128) + parser.add_argument("--base_lr", type=float, default=3e-4) + parser.add_argument("--weight_decay", type=float, default=0.1) + parser.add_argument("--betas", type=float, nargs=2, default=(0.9, 0.99)) + parser.add_argument("--grad_clip", type=float, default=1.0) + parser.add_argument("--max_epochs", type=int, default=200) + parser.add_argument("--warmup_epochs", type=int, default=10) + parser.add_argument("--patience", type=int, default=15) + parser.add_argument("--min_lr_ratio", type=float, default=0.1) + parser.add_argument("--num_workers", type=int, default=4) + parser.add_argument("--device", type=str, default="cuda") + parser.add_argument("--progress_interval", type=int, default=20) + + args = parser.parse_args() + use_eid_split = all( + getattr(args, name) + for name in ("train_eid_file", "val_eid_file", "test_eid_file") + ) + if not use_eid_split and not np.isclose(args.train_ratio + args.val_ratio + args.test_ratio, 1.0): + raise ValueError("train_ratio + val_ratio + test_ratio must equal 1.0") + if args.target_mode == "uts": + args.readout_name = args.readout_name or "same_time_group_end" + args.include_no_event_in_uts_target = True + else: + args.readout_name = args.readout_name or "token" + args.extra_info_types = ( + load_extra_info_types_file(args.extra_info_types_file) + if args.extra_info_types_file is not None + else None + ) + return args + + +def get_lr(epoch: int, args: argparse.Namespace, adaptive_lr: float) -> float: + if epoch < args.warmup_epochs: + return adaptive_lr * (epoch + 1) / args.warmup_epochs + progress = (epoch - args.warmup_epochs) / max(1, args.max_epochs - args.warmup_epochs) + cosine = 0.5 * (1 + math.cos(math.pi * progress)) + return adaptive_lr * (args.min_lr_ratio + cosine * (1 - args.min_lr_ratio)) + + +def move_batch_to_device(batch: Dict[str, torch.Tensor], device: torch.device) -> Dict[str, torch.Tensor]: + non_blocking = device.type == "cuda" + return { + key: value.to(device, non_blocking=non_blocking) + if isinstance(value, torch.Tensor) + else value + for key, value in batch.items() + } + + +def build_model(args: argparse.Namespace, dataset: HealthDataset) -> DeepHealth: + return DeepHealth( + vocab_size=dataset.vocab_size, + n_embd=args.n_embd, + n_head=args.n_head, + n_hist_layer=args.n_hist_layer, + n_tab_layer=args.n_tab_layer, + n_types=dataset.n_types, + n_cont_types=dataset.n_cont_types, + n_categories=dataset.n_categories, + cont_type_ids=dataset.cont_type_ids, + n_bins=args.n_bins, + extra_pool_reduce=args.extra_pool_reduce, + target_mode="next_token", + time_mode=args.time_mode, + dist_mode="exponential", + dropout=args.dropout, + ) + + +def build_next_step_readout(args: argparse.Namespace): + if args.readout_name == "same_time_group_end": + return build_readout("same_time_group_end", reduce=args.readout_reduce) + return build_readout(args.readout_name) + + +def build_next_step_loss(args: argparse.Namespace): + if args.target_mode == "delphi2m": + ignored_tokens = {PAD_IDX, CHECKUP_IDX} + if args.ignore_no_event_in_delphi2m: + ignored_tokens.add(NO_EVENT_IDX) + return build_loss( + "delphi2m", + ignored_tokens=ignored_tokens, + t_min=args.t_min, + max_exp_input=args.max_exp_input, + ce_weight=args.ce_weight, + time_weight=args.time_weight, + ) + return build_loss( + "uts", + ignored_idx={PAD_IDX, CHECKUP_IDX}, + t_min=args.t_min, + max_exp_input=args.max_exp_input, + ) + + +def build_augmented_next_step_targets( + batch_cpu: Dict[str, torch.Tensor], + model_out: DeepHealthOutput, + include_uts_targets: bool, +) -> Dict[str, torch.Tensor]: + hidden_len = model_out.hidden.size(1) + event_len = int(model_out.event_len) + extra_len = hidden_len - event_len + device = model_out.hidden.device + non_blocking = device.type == "cuda" + if extra_len <= 0: + targets = { + "target_event_seq": batch_cpu["target_event_seq"].to(device, non_blocking=non_blocking), + "target_time_seq": batch_cpu["target_time_seq"].to(device, non_blocking=non_blocking), + "readout_mask": batch_cpu["readout_mask"].to(device, non_blocking=non_blocking), + } + if include_uts_targets: + targets["target_dt_unique"] = batch_cpu["target_dt_unique"].to( + device, non_blocking=non_blocking + ) + targets["target_multi_hot"] = batch_cpu["target_multi_hot"].to( + device, non_blocking=non_blocking + ) + return targets + + bsz = batch_cpu["target_event_seq"].size(0) + vocab_size = ( + batch_cpu["target_multi_hot"].size(2) + if include_uts_targets + else None + ) + other_valid = batch_cpu["other_type"] > 0 + extra_time = batch_cpu["other_time"].new_zeros(bsz, extra_len) + extra_mask = torch.zeros(bsz, extra_len, dtype=torch.bool) + for b in range(bsz): + unique_time = torch.unique(batch_cpu["other_time"][b, other_valid[b]], sorted=True) + n_time = min(int(unique_time.numel()), extra_len) + if n_time > 0: + extra_time[b, :n_time] = unique_time[:n_time] + extra_mask[b, :n_time] = True + + target_event_seq = torch.cat( + [ + batch_cpu["target_event_seq"], + torch.full( + (bsz, extra_len), + PAD_IDX, + dtype=batch_cpu["target_event_seq"].dtype, + ), + ], + dim=1, + ) + target_time_seq = torch.cat( + [ + batch_cpu["target_time_seq"], + torch.zeros( + bsz, + extra_len, + dtype=batch_cpu["target_time_seq"].dtype, + ), + ], + dim=1, + ) + readout_mask = torch.cat([batch_cpu["readout_mask"], extra_mask], dim=1) + target_dt_unique = None + target_multi_hot = None + if include_uts_targets: + target_dt_unique = torch.cat( + [ + batch_cpu["target_dt_unique"], + torch.zeros( + bsz, + extra_len, + dtype=batch_cpu["target_dt_unique"].dtype, + ), + ], + dim=1, + ) + target_multi_hot = torch.cat( + [ + batch_cpu["target_multi_hot"], + torch.zeros( + bsz, + extra_len, + vocab_size, + dtype=batch_cpu["target_multi_hot"].dtype, + ), + ], + dim=1, + ) + + for b in range(bsz): + valid_event = batch_cpu["padding_mask"][b].bool() + if not valid_event.any(): + continue + n_event = int(valid_event.sum().item()) + events = torch.cat( + [ + batch_cpu["event_seq"][b, :n_event], + batch_cpu["target_event_seq"][b, n_event - 1:n_event], + ] + ) + times = torch.cat( + [ + batch_cpu["time_seq"][b, :n_event], + batch_cpu["target_time_seq"][b, n_event - 1:n_event], + ] + ) + valid_full = events > PAD_IDX + events = events[valid_full] + times = times[valid_full] + if events.numel() == 0: + continue + + for j in range(extra_len): + if not bool(extra_mask[b, j]): + continue + pos = event_len + j + t = extra_time[b, j] + future = times > t + if not future.any(): + readout_mask[b, pos] = False + continue + + first_idx = int(torch.nonzero(future, as_tuple=False)[0].item()) + next_time = times[first_idx] + next_event = events[first_idx] + target_event_seq[b, pos] = next_event + target_time_seq[b, pos] = next_time + + if not include_uts_targets: + continue + + same_next_time = times == next_time + next_events = events[same_next_time] + valid_next_events = next_events[ + (next_events > PAD_IDX) & (next_events < vocab_size) + ].long() + if valid_next_events.numel() == 0: + readout_mask[b, pos] = False + continue + target_multi_hot[b, pos, valid_next_events] = True + target_dt_unique[b, pos] = next_time - t + + targets = { + "target_event_seq": target_event_seq.to(device, non_blocking=non_blocking), + "target_time_seq": target_time_seq.to(device, non_blocking=non_blocking), + "readout_mask": readout_mask.to(device, non_blocking=non_blocking), + } + if include_uts_targets: + targets["target_dt_unique"] = target_dt_unique.to(device, non_blocking=non_blocking) + targets["target_multi_hot"] = target_multi_hot.to(device, non_blocking=non_blocking) + return targets + + +def compute_next_step_loss( + args: argparse.Namespace, + model: DeepHealth, + readout, + criterion, + batch: Dict[str, torch.Tensor], + device: torch.device, +) -> tuple[torch.Tensor, Dict[str, torch.Tensor]]: + batch_cpu = batch + batch = move_batch_to_device( + {key: batch_cpu[key] for key in MODEL_INPUT_KEYS}, + device, + ) + model_out = model( + event_seq=batch["event_seq"], + time_seq=batch["time_seq"], + sex=batch["sex"], + padding_mask=batch["padding_mask"], + other_type=batch["other_type"], + other_value=batch["other_value"], + other_value_kind=batch["other_value_kind"], + other_time=batch["other_time"], + target_mode="next_token", + return_output=True, + ) + if not isinstance(model_out, DeepHealthOutput): + raise TypeError("DeepHealth return_output=True must return DeepHealthOutput") + targets = build_augmented_next_step_targets( + batch_cpu=batch_cpu, + model_out=model_out, + include_uts_targets=args.target_mode == "uts", + ) + readout_out = readout( + hidden=model_out.hidden, + time_seq=model_out.time_seq, + padding_mask=model_out.padding_mask, + readout_mask=targets["readout_mask"] + if args.readout_name == "same_time_group_end" + else None, + ) + logits = model.calc_risk(readout_out.hidden) + + if args.target_mode == "delphi2m": + loss, parts = criterion( + logits=logits, + target_events=targets["target_event_seq"], + target_times=targets["target_time_seq"], + current_times=model_out.time_seq, + padding_mask=readout_out.readout_mask, + return_components=True, + ) + else: + loss, parts = criterion( + logits=logits, + target_multi_hot=targets["target_multi_hot"], + target_dt_unique=targets["target_dt_unique"], + readout_mask=readout_out.readout_mask, + return_components=True, + ) + if not torch.isfinite(loss): + raise RuntimeError(f"Loss is not finite: {float(loss.detach().cpu())}") + return loss, parts + + +def run_epoch( + logger: logging.Logger, + args: argparse.Namespace, + model: DeepHealth, + readout, + criterion, + loader: DataLoader, + optimizer: AdamW | None, + device: torch.device, + is_train: bool, +) -> float: + model.train(is_train) + readout.train(is_train) + total = torch.zeros((), device=device) + n_batches = 0 + skipped = 0 + parts_sum: Dict[str, torch.Tensor] = {} + desc = "train" if is_train else "val" + progress_interval = max(1, int(args.progress_interval)) + + progress = tqdm(loader, desc=desc, leave=False, dynamic_ncols=True) + for batch_idx, batch in enumerate(progress): + try: + loss, parts = compute_next_step_loss(args, model, readout, criterion, batch, device) + if is_train: + if optimizer is None: + raise ValueError("optimizer is required for training") + optimizer.zero_grad(set_to_none=True) + loss.backward() + if args.grad_clip > 0: + clip_grad_norm_(model.parameters(), args.grad_clip) + optimizer.step() + + total = total + loss.detach() + n_batches += 1 + for name, value in parts.items(): + parts_sum[name] = parts_sum.get(name, torch.zeros((), device=device)) + value.detach() + if (batch_idx + 1) % progress_interval == 0: + avg = total / max(1, n_batches) + postfix = { + "loss": f"{float(loss.detach().cpu()):.4f}", + "avg": f"{float(avg.detach().cpu()):.4f}", + "skipped": skipped, + } + for name, value in parts_sum.items(): + postfix[name] = f"{float((value / max(1, n_batches)).detach().cpu()):.4f}" + progress.set_postfix(postfix) + except RuntimeError as exc: + if "Loss is not finite" not in str(exc): + raise + skipped += 1 + logger.warning(f"Batch {batch_idx} skipped: {str(exc)[:120]}") + + if skipped: + logger.info(f"Skipped {skipped} batches due to non-finite loss") + return float((total / max(1, n_batches)).detach().cpu()) if n_batches else float("inf") + + +def build_metadata( + args: argparse.Namespace, + dataset: HealthDataset, + run_name: str, + train_subset, + val_subset, + test_subset, +) -> Dict[str, Any]: + return { + "run_name": run_name, + "dataset_class": "NextStepHealthDataset", + "collate_fn": "next_step_collate_fn", + "model_class": "DeepHealth", + "model_target_mode": "next_token", + "target_mode": args.target_mode, + "dist_mode": "exponential", + "extra_info_types_file": ( + Path(args.extra_info_types_file).name + if args.extra_info_types_file is not None + else None + ), + "extra_info_types": [int(x) for x in dataset.extra_info_types], + "dataset_metadata": { + "vocab_size": int(dataset.vocab_size), + "n_types": int(dataset.n_types), + "n_cont_types": int(dataset.n_cont_types), + "n_categories": int(dataset.n_categories), + "cont_type_ids": [int(x) for x in dataset.cont_type_ids], + "extra_info_types": [int(x) for x in dataset.extra_info_types], + }, + "split_sizes": { + "train": int(len(train_subset)), + "val": int(len(val_subset)), + "test": int(len(test_subset)), + }, + "resolved_readout_name": args.readout_name, + "resolved_loss_name": args.target_mode, + } + + +def main() -> None: + args = parse_args() + set_seed(args.seed) + device = resolve_device(args.device) + configure_torch_for_training(device) + + run_dir, run_name = create_unique_run_dir( + lambda timestamp: ( + f"{args.time_mode}_exponential_next_token_{args.target_mode}_" + f"gap_{args.no_event_interval_years:g}y_{timestamp}" + ) + ) + logger = setup_logging(run_dir) + + logger.info(f"Starting next-step training run: {run_name}") + logger.info(f"Device: {device}") + logger.info(f"extra_info_types: {format_extra_info_types(args.extra_info_types)}") + logger.info(f"readout={args.readout_name}, target_mode={args.target_mode}") + + dataset = HealthDataset( + data_prefix=args.data_prefix, + labels_file=args.labels_file, + no_event_interval_years=args.no_event_interval_years, + include_no_event_in_uts_target=args.include_no_event_in_uts_target, + extra_info_types=args.extra_info_types, + ) + if args.train_eid_file and args.val_eid_file and args.test_eid_file: + train_subset, val_subset, test_subset = split_dataset_by_eid_files( + dataset=dataset, + train_eid_file=args.train_eid_file, + val_eid_file=args.val_eid_file, + test_eid_file=args.test_eid_file, + ) + logger.info( + "Using eid split files: " + f"train={args.train_eid_file}, val={args.val_eid_file}, test={args.test_eid_file}" + ) + else: + train_subset, val_subset, test_subset = split_dataset( + dataset=dataset, + train_ratio=args.train_ratio, + val_ratio=args.val_ratio, + test_ratio=args.test_ratio, + seed=args.seed, + ) + logger.info( + f"Using random ratio split: train={args.train_ratio}, " + f"val={args.val_ratio}, test={args.test_ratio}, seed={args.seed}" + ) + logger.info( + f"Samples: train={len(train_subset)}, val={len(val_subset)}, test={len(test_subset)}" + ) + + train_loader = DataLoader( + train_subset, + batch_size=args.batch_size, + sampler=RandomSampler(train_subset, generator=torch.Generator().manual_seed(args.seed)), + collate_fn=collate_fn, + num_workers=args.num_workers, + pin_memory=device.type == "cuda", + persistent_workers=args.num_workers > 0, + prefetch_factor=2 if args.num_workers > 0 else None, + ) + val_loader = DataLoader( + val_subset, + batch_size=args.batch_size, + shuffle=False, + collate_fn=collate_fn, + num_workers=args.num_workers, + pin_memory=device.type == "cuda", + persistent_workers=args.num_workers > 0, + prefetch_factor=2 if args.num_workers > 0 else None, + ) + test_loader = DataLoader( + test_subset, + batch_size=args.batch_size, + shuffle=False, + collate_fn=collate_fn, + num_workers=args.num_workers, + pin_memory=device.type == "cuda", + persistent_workers=args.num_workers > 0, + prefetch_factor=2 if args.num_workers > 0 else None, + ) + + model = build_model(args, dataset).to(device) + readout = build_next_step_readout(args).to(device) + criterion = build_next_step_loss(args) + optimizer = AdamW( + model.parameters(), + lr=args.base_lr, + betas=tuple(args.betas), + weight_decay=args.weight_decay, + ) + adaptive_lr = args.base_lr * math.sqrt(args.batch_size / 128) + + save_config( + args, + run_dir / "train_config.json", + extra=build_metadata(args, dataset, run_name, train_subset, val_subset, test_subset), + ) + + best_val = float("inf") + patience = 0 + history = [] + best_model_path = run_dir / "best_model.pt" + start = time.time() + + for epoch in range(args.max_epochs): + lr = get_lr(epoch, args, adaptive_lr) + set_optimizer_lr(optimizer, lr) + + train_loss = run_epoch(logger, args, model, readout, criterion, train_loader, optimizer, device, True) + with torch.no_grad(): + val_loss = run_epoch(logger, args, model, readout, criterion, val_loader, None, device, False) + + is_best = val_loss < best_val + if is_best: + best_val = val_loss + patience = 0 + save_checkpoint(model, best_model_path) + else: + patience += 1 + + logger.info( + f"Epoch {epoch + 1}/{args.max_epochs} | lr={lr:.6f} | " + f"train_loss={train_loss:.6f} | val_loss={val_loss:.6f} | " + f"best_val_loss={best_val:.6f} | patience={patience}/{args.patience} | " + f"elapsed={time.time() - start:.1f}s" + ) + history.append({ + "epoch": epoch + 1, + "lr": lr, + "train_loss": train_loss, + "val_loss": val_loss, + "best_val_loss": best_val, + "is_best": int(is_best), + }) + if patience >= args.patience: + logger.info(f"Early stopping triggered at epoch {epoch + 1}") + break + + with (run_dir / "history.json").open("w", encoding="utf-8") as f: + json.dump(history, f, indent=2) + + logger.info("Evaluating best model on next-step test split...") + model.load_state_dict(torch.load(best_model_path, map_location=device)) + with torch.no_grad(): + test_loss = run_epoch(logger, args, model, readout, criterion, test_loader, None, device, False) + logger.info(f"Test loss: {test_loss:.6f}") + logger.info(f"Best checkpoint: {best_model_path}") + + +if __name__ == "__main__": + main() diff --git a/train_util.py b/train_util.py new file mode 100644 index 0000000..1fe578c --- /dev/null +++ b/train_util.py @@ -0,0 +1,329 @@ +from __future__ import annotations + +import json +import logging +import sys +import time +import csv +from datetime import datetime +from pathlib import Path +from typing import Any, Dict, Iterable, Tuple + +import numpy as np +import torch +from torch.optim import AdamW +from torch.utils.data import Subset + +from dataset import AllFutureHealthDataset, HealthDataset +from models import DeepHealth + + +def create_unique_run_dir(name_fn, runs_root: Path = Path("runs")) -> tuple[Path, str]: + while True: + timestamp = datetime.now().strftime("%Y%m%d_%H%M%S") + run_name = name_fn(timestamp) + run_dir = runs_root / run_name + try: + run_dir.mkdir(parents=True, exist_ok=False) + return run_dir, run_name + except FileExistsError: + time.sleep(1.0) + + +def setup_logging(run_dir: Path) -> logging.Logger: + run_dir.mkdir(parents=True, exist_ok=True) + logger = logging.getLogger("DeepHealth") + logger.setLevel(logging.INFO) + logger.handlers.clear() + + formatter = logging.Formatter( + "%(asctime)s - %(levelname)s - %(message)s", + datefmt="%Y-%m-%d %H:%M:%S", + ) + + console_handler = logging.StreamHandler(sys.stdout) + console_handler.setLevel(logging.INFO) + console_handler.setFormatter(formatter) + logger.addHandler(console_handler) + + file_handler = logging.FileHandler(run_dir / "train.log", mode="w") + file_handler.setLevel(logging.INFO) + file_handler.setFormatter(formatter) + logger.addHandler(file_handler) + + return logger + + +def set_seed(seed: int) -> None: + np.random.seed(seed) + torch.manual_seed(seed) + if torch.cuda.is_available(): + torch.cuda.manual_seed(seed) + + +def load_extra_info_types_file(path: str) -> list[int]: + file_path = Path(path) + if not file_path.is_file(): + raise FileNotFoundError(f"extra_info_types_file not found: {path}") + + text = file_path.read_text(encoding="utf-8").strip() + if not text: + return [] + + if text.startswith("["): + raw_items = json.loads(text) + if not isinstance(raw_items, list): + raise ValueError("extra_info_types_file JSON must be a list") + else: + raw_items = [] + for line in text.splitlines(): + line = line.split("#", 1)[0].strip() + if line: + raw_items.extend(line.replace(",", " ").replace(";", " ").split()) + + try: + return [int(x) for x in raw_items] + except (TypeError, ValueError) as exc: + raise ValueError(f"Invalid extra info type id in {path}") from exc + + +def format_extra_info_types(extra_info_types: Iterable[int] | None) -> str: + if extra_info_types is None: + return "all" + values = [int(x) for x in extra_info_types] + if not values: + return "none" + return str(values) + + +def load_eid_file(path: str | Path) -> set[int]: + file_path = Path(path) + if not file_path.is_file(): + raise FileNotFoundError(f"eid split file not found: {file_path}") + with file_path.open(newline="", encoding="utf-8-sig") as f: + reader = csv.DictReader(f) + if reader.fieldnames is None or "eid" not in reader.fieldnames: + raise ValueError( + f"eid split file must contain an 'eid' column: {file_path}" + ) + out: set[int] = set() + for row in reader: + raw = (row.get("eid") or "").strip() + if raw: + out.add(int(raw)) + if not out: + raise ValueError(f"eid split file is empty: {file_path}") + return out + + +def configure_torch_for_training(device: torch.device) -> None: + if device.type != "cuda": + return + torch.backends.cuda.matmul.allow_tf32 = True + torch.backends.cudnn.allow_tf32 = True + if hasattr(torch, "set_float32_matmul_precision"): + torch.set_float32_matmul_precision("high") + + +def resolve_device(device_arg: str) -> torch.device: + requested = device_arg.strip().lower() + if requested == "cpu": + return torch.device("cpu") + if requested == "cuda": + return torch.device("cuda" if torch.cuda.is_available() else "cpu") + if requested.startswith("cuda:"): + if not torch.cuda.is_available(): + return torch.device("cpu") + index = int(requested.split(":", 1)[1]) + if index < 0 or index >= torch.cuda.device_count(): + raise ValueError(f"Requested CUDA device is out of range: {device_arg}") + return torch.device(f"cuda:{index}") + raise ValueError(f"Unsupported device: {device_arg}") + + +def split_dataset( + dataset: HealthDataset, + train_ratio: float, + val_ratio: float, + test_ratio: float, + seed: int, +) -> Tuple[Subset, Subset, Subset]: + total = train_ratio + val_ratio + test_ratio + if not np.isclose(total, 1.0, atol=1e-6): + raise ValueError(f"train/val/test ratios must sum to 1.0, got {total}") + + indices = np.random.RandomState(seed).permutation(len(dataset)) + n_train = int(len(dataset) * train_ratio) + n_val = int(len(dataset) * val_ratio) + return ( + Subset(dataset, indices[:n_train]), + Subset(dataset, indices[n_train:n_train + n_val]), + Subset(dataset, indices[n_train + n_val:]), + ) + + +def split_dataset_by_eid_files( + dataset: HealthDataset, + train_eid_file: str | Path, + val_eid_file: str | Path, + test_eid_file: str | Path, +) -> Tuple[Subset, Subset, Subset]: + split_sets = { + "train": load_eid_file(train_eid_file), + "val": load_eid_file(val_eid_file), + "test": load_eid_file(test_eid_file), + } + overlaps = ( + split_sets["train"] & split_sets["val"], + split_sets["train"] & split_sets["test"], + split_sets["val"] & split_sets["test"], + ) + if any(overlaps): + raise ValueError("eid split files must be disjoint") + + split_indices: Dict[str, list[int]] = {"train": [], "val": [], "test": []} + for idx, sample in enumerate(dataset.samples): + eid = int(sample["eid"]) + for split_name, eid_set in split_sets.items(): + if eid in eid_set: + split_indices[split_name].append(idx) + break + + missing = [name for name, indices in split_indices.items() if not indices] + if missing: + raise ValueError(f"Empty dataset split(s) after eid filtering: {missing}") + + return ( + Subset(dataset, np.asarray(split_indices["train"], dtype=np.int64)), + Subset(dataset, np.asarray(split_indices["val"], dtype=np.int64)), + Subset(dataset, np.asarray(split_indices["test"], dtype=np.int64)), + ) + + +def split_all_future_datasets( + train_dataset: AllFutureHealthDataset, + val_dataset: AllFutureHealthDataset, + test_dataset: AllFutureHealthDataset, + train_ratio: float, + val_ratio: float, + test_ratio: float, + seed: int, +) -> Tuple[Subset, Subset, Subset]: + total = train_ratio + val_ratio + test_ratio + if not np.isclose(total, 1.0, atol=1e-6): + raise ValueError(f"train/val/test ratios must sum to 1.0, got {total}") + + patient_indices = np.random.RandomState(seed).permutation(len(train_dataset.patients)) + n_train = int(len(patient_indices) * train_ratio) + n_val = int(len(patient_indices) * val_ratio) + train_patient_idx = patient_indices[:n_train] + val_patient_set = set(int(x) for x in patient_indices[n_train:n_train + n_val]) + test_patient_set = set(int(x) for x in patient_indices[n_train + n_val:]) + + val_query_idx = [ + i for i, (pidx, _t_query) in enumerate(val_dataset.valid_queries) + if int(pidx) in val_patient_set + ] + test_query_idx = [ + i for i, (pidx, _t_query) in enumerate(test_dataset.valid_queries) + if int(pidx) in test_patient_set + ] + if not val_query_idx: + raise ValueError("All-future validation split has no valid query samples.") + if not test_query_idx: + raise ValueError("All-future test split has no valid query samples.") + + return ( + Subset(train_dataset, train_patient_idx), + Subset(val_dataset, np.asarray(val_query_idx, dtype=np.int64)), + Subset(test_dataset, np.asarray(test_query_idx, dtype=np.int64)), + ) + + +def split_all_future_datasets_by_eid_files( + train_dataset: AllFutureHealthDataset, + val_dataset: AllFutureHealthDataset, + test_dataset: AllFutureHealthDataset, + train_eid_file: str | Path, + val_eid_file: str | Path, + test_eid_file: str | Path, +) -> Tuple[Subset, Subset, Subset]: + split_sets = { + "train": load_eid_file(train_eid_file), + "val": load_eid_file(val_eid_file), + "test": load_eid_file(test_eid_file), + } + overlaps = ( + split_sets["train"] & split_sets["val"], + split_sets["train"] & split_sets["test"], + split_sets["val"] & split_sets["test"], + ) + if any(overlaps): + raise ValueError("eid split files must be disjoint") + + train_patient_idx = [ + idx + for idx, patient in enumerate(train_dataset.patients) + if int(patient["eid"]) in split_sets["train"] + ] + val_query_idx = [ + idx + for idx, (pidx, _t_query) in enumerate(val_dataset.valid_queries) + if int(val_dataset.patients[int(pidx)]["eid"]) in split_sets["val"] + ] + test_query_idx = [ + idx + for idx, (pidx, _t_query) in enumerate(test_dataset.valid_queries) + if int(test_dataset.patients[int(pidx)]["eid"]) in split_sets["test"] + ] + + if not train_patient_idx: + raise ValueError("All-future training eid split has no patients.") + if not val_query_idx: + raise ValueError("All-future validation eid split has no valid query samples.") + if not test_query_idx: + raise ValueError("All-future test eid split has no valid query samples.") + + return ( + Subset(train_dataset, np.asarray(train_patient_idx, dtype=np.int64)), + Subset(val_dataset, np.asarray(val_query_idx, dtype=np.int64)), + Subset(test_dataset, np.asarray(test_query_idx, dtype=np.int64)), + ) + + +def build_optimizer(args: Any, model: DeepHealth) -> AdamW: + return AdamW( + model.parameters(), + lr=args.base_lr, + betas=tuple(args.betas), + weight_decay=args.weight_decay, + ) + + +def set_optimizer_lr(optimizer: AdamW, lr: float) -> None: + for param_group in optimizer.param_groups: + param_group["lr"] = lr + + +def save_checkpoint(model: DeepHealth, checkpoint_path: Path) -> None: + torch.save(model.state_dict(), checkpoint_path) + + +def save_config( + args: Any, + config_path: Path, + extra: Dict[str, Any] | None = None, +) -> None: + config: Dict[str, Any] = {} + for key, value in vars(args).items(): + if isinstance(value, tuple): + config[key] = list(value) + elif isinstance(value, list): + config[key] = value + elif isinstance(value, (int, float, str, bool, type(None))): + config[key] = value + else: + config[key] = str(value) + if extra: + config.update(extra) + config_path.write_text(json.dumps(config, indent=2), encoding="utf-8")