Skip to content

analytics

Clinical-domain logic lives beside the concept sets and policies that give it meaning. The domain-neutral core and episodes packages provide the underlying resolution and traversal mechanisms.

oncology

API Capability
OncologyEpisode Classifies episode purpose and modality; traverses events linked to the episode and its direct children.
structural_modalities / concept_modalities Preserve every evidenced modality so mixed treatment and SACT classification disagreements remain visible.
structural_modality / concept_modality Select one deterministic modality in radiotherapy, surgery, diagnostic/staging, SACT priority order.
OncologyProcedure / OncologyDrugExposure Add governed is_radiotherapy, is_surgery, is_diagnostic_staging, and is_sact questions to CDM facts.
RTDoseSummary.from_procedures(...) Constructs one radiotherapy summary; summarize_rt_procedures_by(...) groups before construction.
SACTDoseSummary.from_exposures(...) Constructs one SACT summary; summarize_sact_exposures_by(...) groups before construction.
OncologyEpisodeEvent Resolves oncology-aware facts while retaining episode-event diagnostics.

Governed membership has two access modes:

Access form Behaviour
Loaded instance property Expands once per vocabulary identity, then uses cached O(1) membership. Initial classification requires a live session; a cached result remains the snapshot computed while the instance was attached.
Class-level hybrid expression Emits a database subquery for each query and does not use the Python expansion cache.

Bases: OncologyCriticalWeightLossMixin, OncologySACTDosingMixin, OncologyRTDosingMixin, OncologyEpisodeEventMixin, EpisodeView

Oncology-aware episode view.

This composes generic episode hierarchy support, oncology-aware Episode_Event resolution, body-metric adverse-event grading, and treatment dose-summary interfaces. Modality classification exposes both structural treatment evidence, such as linked drug exposures, and governed concept evidence, such as SACT-classified drug concepts, so callers can audit disagreements.

primary_episode property

primary_episode: Self

child_treatment_episodes cached property

child_treatment_episodes: list[Self]

structural_modalities cached property

structural_modalities: frozenset[OncologyModality]

All modalities supported by linked event structure.

Any linked drug exposure is treated as structural SACT evidence, while radiotherapy, surgery, and diagnostic/staging require governed procedure concept membership. Events linked to direct child episodes are included.

structural_modality cached property

structural_modality: OncologyModality

Highest-priority structural modality, or UNKNOWN when none apply.

Priority is radiotherapy, surgery, diagnostic/staging, then SACT.

concept_modalities cached property

concept_modalities: frozenset[OncologyModality]

All modalities supported by linked procedure and drug concept identity.

This is intentionally distinct from structural_modalities so SACT disagreements remain visible.

concept_modality cached property

concept_modality: OncologyModality

Highest-priority concept modality, or UNKNOWN when none apply.

Priority is radiotherapy, surgery, diagnostic/staging, then SACT.

child_treatment_episodes_by_modality cached property

child_treatment_episodes_by_modality: dict[
    OncologyModality, list[Self]
]

child_treatment_episodes_by_concept_modality cached property

child_treatment_episodes_by_concept_modality: dict[
    OncologyModality, list[Self]
]

is_disease_episode

is_disease_episode() -> bool

is_overarching

is_overarching() -> bool

is_treatment_episode

is_treatment_episode() -> bool

is_treatment_regimen

is_treatment_regimen() -> bool

is_treatment_cycle

is_treatment_cycle() -> bool

Radiotherapy procedure summary for one caller-chosen site/group key.

OMOP procedure rows do not provide one universal RT dose model. This summary exposes dates, procedure concepts, modifiers, counts, and evaluability so a site-specific RT policy can decide what is clinically meaningful.

from_procedures classmethod

from_procedures(
    procedures: Sequence[OncologyProcedure],
    *,
    group_key: object,
) -> Self

Summarize radiotherapy procedure rows for one grouping key.

Bases: DrugExposureSummary

SACT dose summary for one caller-chosen drug grouping.

This is deliberately a summary interface, not a dose-reduction rule. It preserves mixed/missing units as evaluability states for downstream SACT policy to interpret.

from_exposures classmethod

from_exposures(
    exposures: Sequence[Drug_Exposure], *, group_key: object
) -> Self

Summarize SACT exposures and attach dose evaluability policy.

Construction is field-based and therefore accepts the base OMOP exposure type. Oncology filtering belongs to sact_exposures before this summary boundary; keeping the inherited input type also preserves substitutability.

body_metrics

API Capability
MeasurementReading.from_measurement(...) Reduces an OMOP measurement to the fields used by calculations and records its resolution source.
MeasurementSeriesMixin Resolves normalized measurement series for an episode.
WeightTrajectoryMixin Exposes normalized weight and height, BMI, BSA, windowed change, trajectories, and a dict-shaped typed summary.
WeightChange Represents percentage change and whether it was evaluable; unevaluable change has pct_change=None.
WeightTrajectorySummary Types the DataFrame- and JSON-friendly mapping returned by weight_trajectory_summary().

A resolved numeric measurement reduced to the fields trajectory math needs.

from_measurement classmethod

from_measurement(
    measurement: Measurement, *, source: ReadingSource
) -> Self

Reduce an OMOP measurement row to trajectory input fields.

Episode mixin exposing normalized weight, height, BMI, and trajectories.

Subclasses may set _body_metric_rules to avoid loading the default omop-semantics-backed concept IDs.

weight_readings cached property

weight_readings: list[MeasurementReading]

Weight readings normalized to kg.

height_readings_cm cached property

height_readings_cm: list[MeasurementReading]

Height readings normalized to cm and resolved without an episode date window.

height_m property

height_m: Optional[float]

baseline_weight property

baseline_weight: Optional[MeasurementReading]

latest_weight property

latest_weight: Optional[MeasurementReading]

baseline_bmi property

baseline_bmi: Optional[float]

baseline_bsa_mosteller_m2 property

baseline_bsa_mosteller_m2: Optional[float]

pct_change_from_baseline

pct_change_from_baseline(
    as_of: Optional[MeasurementReading] = None,
) -> WeightChange

pct_change_over

pct_change_over(days: int) -> WeightChange

pct_change_trajectory

pct_change_trajectory() -> list[WeightTrajectoryPoint]

sustained_loss

sustained_loss(
    threshold_pct: float = 5.0, min_consecutive: int = 2
) -> Optional[bool]

weight_trajectory_summary

weight_trajectory_summary() -> WeightTrajectorySummary

adverse_events

API Policy
ctcae_weight_loss_grade(...) Grades percentage weight loss against CTCAE-style bins.
martin_weight_loss_grade(...) Applies the Martin et al. BMI-adjusted matrix.
critical_weight_loss_grade(...) Uses the Martin matrix when BMI is available and otherwise falls back to CTCAE-style bins.

CTCAEWeightLoss

CTCAE-style weight-loss severity from percent weight change only.

This implements physiological percent-loss bins.

CTCAE intervention qualifiers such as hospitalisation, tube feeding, or TPN are not inferred here.

MartinWeightLoss

Martin et al. BMI-adjusted percent-weight-loss grading.

Source: Martin L, Senesse P, Gioulbasanis I, et al. "Diagnostic criteria for the classification of cancer-associated weight loss." J Clin Oncol. 2015;33(1):90-99. The published system crosses five percent-weight-loss categories with five BMI categories to give grades 0-4.

This matrix is kept in adverse events because it is clinical severity policy over body measurements, not body-measurement arithmetic itself.

critical_weight_loss_grade

critical_weight_loss_grade(
    pct_change: Optional[float], bmi: Optional[float]
) -> Optional[int]

Critical-weight-loss grade using Martin where BMI is available.

Falls back to CTCAE-style percent-weight-loss grading when percent change is evaluable but BMI is not, preserving coverage without guessing BMI.