Skip to content

Stores

cms_icd.stores.ReadOnlyStore

ReadOnlyStore(values: Mapping[str, T])

A deterministic read-only mapping.

Examples:

>>> store = ReadOnlyStore({"b": 2, "a": 1})
>>> list(store)
['b', 'a']
>>> store["a"]
1
Source code in src/cms_icd/stores.py
def __init__(self, values: Mapping[str, T]) -> None:
    self._values = MappingProxyType(dict(values))

cms_icd.stores.TabularStore

TabularStore(values: Mapping[str, Node], code_lookup: Mapping[str, str], roots: Iterable[str])

Read-only ICD tabular hierarchy.

children_ids always contains direct children. Recursive relationships are requested explicitly.

Examples:

>>> root = Node("cm", "cm", children_ids=("I10",))
>>> code = Code("I10", "I10", "Essential hypertension", parent_id="cm")
>>> store = TabularStore({"cm": root, "I10": code}, {"I10": "I10"}, ("cm",))
>>> [node.id for node in store.parents("I10")]
['cm']
>>> [node.name for node in store.leaves("cm")]
['I10']
Source code in src/cms_icd/stores.py
def __init__(
    self,
    values: Mapping[str, Node],
    code_lookup: Mapping[str, str],
    roots: Iterable[str],
) -> None:
    super().__init__(values)
    self._code_lookup = MappingProxyType(dict(code_lookup))
    self._normalized_code_lookup = MappingProxyType(
        {code.replace(".", ""): node_id for code, node_id in code_lookup.items()}
    )
    self._roots = tuple(roots)
    self._parents_cache: dict[str, tuple[Node, ...]] = {}
    self._parents_lock = Lock()

lookup property

lookup: Mapping[str, str]

Map normalized ICD code strings to tabular node identifiers.

roots property

roots: tuple[str, ...]

Return root node identifiers.

by_code

by_code(code: str) -> Node

Return the node for a dotted or compact ICD code.

Source code in src/cms_icd/stores.py
def by_code(self, code: str) -> Node:
    """Return the node for a dotted or compact ICD code."""
    return self[self._node_id(code)]

parents

parents(code_or_id: str) -> tuple[Node, ...]

Return parents from the immediate parent to the root.

Source code in src/cms_icd/stores.py
def parents(self, code_or_id: str) -> tuple[Node, ...]:
    """Return parents from the immediate parent to the root."""
    node_id = self._node_id(code_or_id)
    cached = self._parents_cache.get(node_id)
    if cached is not None:
        return cached
    node = self[node_id]
    result: list[Node] = []
    while node.parent_id:
        node = self[node.parent_id]
        result.append(node)
    parents = tuple(result)
    with self._parents_lock:
        return self._parents_cache.setdefault(node_id, parents)

children

children(code_or_id: str) -> tuple[Node, ...]

Return direct children of a node.

Source code in src/cms_icd/stores.py
def children(self, code_or_id: str) -> tuple[Node, ...]:
    """Return direct children of a node."""
    node_id = self._node_id(code_or_id)
    return tuple(self[child_id] for child_id in self[node_id].children_ids)

descendants

descendants(code_or_id: str) -> tuple[Node, ...]

Return all descendants in deterministic depth-first order.

Source code in src/cms_icd/stores.py
def descendants(self, code_or_id: str) -> tuple[Node, ...]:
    """Return all descendants in deterministic depth-first order."""
    result: list[Node] = []
    for child in self.children(code_or_id):
        result.append(child)
        result.extend(self.descendants(child.id))
    return tuple(result)

leaves

leaves(code_or_id: str) -> tuple[Code, ...]

Return assignable descendant codes.

Source code in src/cms_icd/stores.py
def leaves(self, code_or_id: str) -> tuple[Code, ...]:
    """Return assignable descendant codes."""
    return tuple(
        node
        for node in self.descendants(code_or_id)
        if isinstance(node, Code) and node.assignable
    )

siblings

siblings(code_or_id: str) -> tuple[Node, ...]

Return direct siblings, excluding the requested node.

Source code in src/cms_icd/stores.py
def siblings(self, code_or_id: str) -> tuple[Node, ...]:
    """Return direct siblings, excluding the requested node."""
    node_id = self._node_id(code_or_id)
    node = self[node_id]
    if not node.parent_id:
        return ()
    return tuple(
        self[item] for item in self[node.parent_id].children_ids if item != node_id
    )

lowest_common_ancestor

lowest_common_ancestor(codes_or_ids: Iterable[str]) -> Node | None

Return the deepest hierarchy node shared by all supplied codes.

The requested nodes themselves participate in the comparison. An empty input has no common ancestor; unknown codes retain the normal mapping KeyError.

Source code in src/cms_icd/stores.py
def lowest_common_ancestor(self, codes_or_ids: Iterable[str]) -> Node | None:
    """Return the deepest hierarchy node shared by all supplied codes.

    The requested nodes themselves participate in the comparison. An empty input has
    no common ancestor; unknown codes retain the normal mapping ``KeyError``.
    """
    values = tuple(codes_or_ids)
    if not values:
        return None
    paths: list[tuple[Node, ...]] = []
    for value in values:
        node_id = self._node_id(value)
        node = self[node_id]
        paths.append((node, *self.parents(node_id)))
    shared = set.intersection(*({node.id for node in path} for path in paths))
    return next((node for node in paths[0] if node.id in shared), None)

cms_icd.stores.IndexStore

IndexStore(values: Mapping[str, T])

Read-only alphabetic-index hierarchy.

Source code in src/cms_icd/stores.py
def __init__(self, values: Mapping[str, T]) -> None:
    self._values = MappingProxyType(dict(values))

parents

parents(term_id: str) -> tuple[Term, ...]

Return index parents from immediate parent to main term.

Source code in src/cms_icd/stores.py
def parents(self, term_id: str) -> tuple[Term, ...]:
    """Return index parents from immediate parent to main term."""
    term = self[term_id]
    result: list[Term] = []
    while term.parent_id:
        term = self[term.parent_id]
        result.append(term)
    return tuple(result)

children

children(term_id: str) -> tuple[Term, ...]

Return direct child terms.

Source code in src/cms_icd/stores.py
def children(self, term_id: str) -> tuple[Term, ...]:
    """Return direct child terms."""
    return tuple(self[item] for item in self[term_id].children_ids)

descendants

descendants(term_id: str) -> tuple[Term, ...]

Return all descendant terms in depth-first order.

Source code in src/cms_icd/stores.py
def descendants(self, term_id: str) -> tuple[Term, ...]:
    """Return all descendant terms in depth-first order."""
    result: list[Term] = []
    for child in self.children(term_id):
        result.append(child)
        result.extend(self.descendants(child.id))
    return tuple(result)

main_terms

main_terms() -> tuple[Term, ...]

Return all top-level main terms.

Source code in src/cms_icd/stores.py
def main_terms(self) -> tuple[Term, ...]:
    """Return all top-level main terms."""
    return tuple(term for term in self.values() if not term.parent_id)

cms_icd.stores.GuidelineStore

GuidelineStore(values: Mapping[str, Guideline], titles: Mapping[str, str] | None = None, preambles: Mapping[str, str] | None = None)

Hierarchical guideline sections keyed with dotted identifiers.

Examples:

>>> item = Guideline("I_A_1", "I.A.1", "Example", "Body")
>>> titles = {"I": "Section", "I.A": "Conventions"}
>>> store = GuidelineStore({"I.A.1": item}, titles)
>>> store.descendants("I")
('I.A.1',)
>>> store["I.A.1"].content
'Body'
Source code in src/cms_icd/stores.py
def __init__(
    self,
    values: Mapping[str, Guideline],
    titles: Mapping[str, str] | None = None,
    preambles: Mapping[str, str] | None = None,
) -> None:
    super().__init__(values)
    self._titles = MappingProxyType(dict(titles or {}))
    self._preambles = MappingProxyType(dict(preambles or {}))

titles property

titles: Mapping[str, str]

Return titles for both leaf and non-leaf guideline sections.

preambles property

preambles: Mapping[str, str]

Return text appearing before the first child of container sections.

descendants

descendants(prefix: str) -> tuple[str, ...]

Return naturally sorted leaf keys below a prefix.

Source code in src/cms_icd/stores.py
def descendants(self, prefix: str) -> tuple[str, ...]:
    """Return naturally sorted leaf keys below a prefix."""
    return tuple(
        sorted(
            (key for key in self._values if key.startswith(prefix + ".")),
            key=_natural_sort_key,
        )
    )

ancestors

ancestors(key: str) -> tuple[tuple[str, str], ...]

Return titled ancestor keys from outermost to innermost.

Source code in src/cms_icd/stores.py
def ancestors(self, key: str) -> tuple[tuple[str, str], ...]:
    """Return titled ancestor keys from outermost to innermost."""
    parts = key.split(".")
    return tuple(
        (ancestor, self._titles[ancestor])
        for index in range(1, len(parts))
        if (ancestor := ".".join(parts[:index])) in self._titles
    )