Skip to content

Patients

matchminer_ai.patients

Patient summarization workflows.

summarize_patients

summarize_patients(notes: DataFrame, *, config: MMAIConfig | None = None, existing_summaries: DataFrame | None = None, return_metadata: bool = False, return_qc: bool = False) -> pd.DataFrame | tuple[pd.DataFrame, dict] | tuple[pd.DataFrame, pd.DataFrame] | tuple[pd.DataFrame, dict, pd.DataFrame]

Summarize longitudinal patient notes into a cancer history summary and evidence related to general clinical trial exclusion criteria.

Parameters:

Name Type Description Default
notes DataFrame

Note-level input. One row per note.

Expected columns

patient_id : str Unique patient identifier. note_text : str Full note text. note_date : str or datetime Date of the note.

required
existing_summaries DataFrame

Optional patient-level prior summaries used as the starting state for serial updates.

Expected columns

patient_id : str Unique patient identifier. patient_summary : str Existing full patient summary text to update.

None
return_metadata bool

When True, also return a metadata dict containing the config snapshot and model metadata for this run.

False
return_qc bool

When True, also return a QC report DataFrame for this run.

False

Returns:

Type Description
DataFrame

Patient-level DataFrame. One row per patient.

Columns

patient_id : str Original patient identifier. cancer_history_summary : str Summary of the patient's cancer history. general_exclusion_criteria_evidence : str Summary of conditions / findings that correspond to common clinical trial exclusion criteria.

Debug Columns (Available only if pipeline initialized with debug_mode=True)


patient_answer_text : str Text the package treated as the LLM answer and used for postprocessing. patient_reasoning_text : str Optional separate reasoning trace returned by the backend or extracted by the configured reasoning parser.

tuple[DataFrame, dict]

When return_metadata is True, returns the DataFrame plus a metadata dict.

tuple[DataFrame, DataFrame]

When return_qc is True, returns the DataFrame plus a QC report DataFrame.

tuple[DataFrame, dict, DataFrame]

When return_metadata and return_qc are True, returns the DataFrame, metadata dict, and QC report DataFrame.

Source code in src/matchminer_ai/patients/__init__.py
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
def summarize_patients(
    notes: pd.DataFrame,
    *,
    config: MMAIConfig | None = None,
    existing_summaries: pd.DataFrame | None = None,
    return_metadata: bool = False,
    return_qc: bool = False,
) -> (
    pd.DataFrame
    | tuple[pd.DataFrame, dict]
    | tuple[pd.DataFrame, pd.DataFrame]
    | tuple[pd.DataFrame, dict, pd.DataFrame]
):
    """
    Summarize longitudinal patient notes into a cancer history summary and
    evidence related to general clinical trial exclusion criteria.

    Parameters
    ----------
    notes : pd.DataFrame
        Note-level input. One row per note.

        Expected columns
        ----------------
        patient_id : str
            Unique patient identifier.
        note_text : str
            Full note text.
        note_date : str or datetime
            Date of the note.
    existing_summaries : pd.DataFrame, optional
        Optional patient-level prior summaries used as the starting state for
        serial updates.

        Expected columns
        ----------------
        patient_id : str
            Unique patient identifier.
        patient_summary : str
            Existing full patient summary text to update.
    return_metadata : bool, optional
        When True, also return a metadata dict containing the config snapshot
        and model metadata for this run.
    return_qc : bool, optional
        When True, also return a QC report DataFrame for this run.

    Returns
    -------
    pd.DataFrame
        Patient-level DataFrame. One row per patient.

        Columns
        -------
        patient_id : str
            Original patient identifier.
        cancer_history_summary : str
            Summary of the patient's cancer history.
        general_exclusion_criteria_evidence : str
            Summary of conditions / findings that correspond to common
            clinical trial exclusion criteria.

        Debug Columns
        (Available only if pipeline initialized with debug_mode=True)
        -------------------------------------------------------------
        patient_answer_text : str
            Text the package treated as the LLM answer and used for
            postprocessing.
        patient_reasoning_text : str
            Optional separate reasoning trace returned by the backend or
            extracted by the configured reasoning parser.
    tuple[pd.DataFrame, dict]
        When return_metadata is True, returns the DataFrame plus a metadata dict.
    tuple[pd.DataFrame, pd.DataFrame]
        When return_qc is True, returns the DataFrame plus a QC report DataFrame.
    tuple[pd.DataFrame, dict, pd.DataFrame]
        When return_metadata and return_qc are True, returns the DataFrame,
        metadata dict, and QC report DataFrame.

    """
    logger = logging.getLogger(__name__)
    resolved_config = config or load_default_preset()
    if not isinstance(resolved_config, MMAIConfig):
        raise TypeError("config must be an MMAIConfig instance or None.")

    required_columns = [
        "patient_id",
        "note_text",
        "note_date",
    ]
    missing = [col for col in required_columns if col not in notes.columns]
    if missing:
        raise ValueError(
            "summarize_patients requires columns "
            f"{', '.join(missing)} in the input DataFrame."
        )

    logger.info("Preparing serial patient summarization for %d notes.", len(notes))
    summary_result = summarize_patient_notes(
        notes,
        config=resolved_config,
        existing_summaries=existing_summaries,
        return_qc=return_qc,
    )
    if return_qc:
        summaries, metadata, qc_report = cast(
            tuple[pd.DataFrame, dict, pd.DataFrame],
            summary_result,
        )
    else:
        summaries, metadata = cast(
            tuple[pd.DataFrame, dict],
            summary_result,
        )
        qc_report = None
    logger.info("Patient summarization complete. Produced %d rows.", len(summaries))

    if return_metadata:
        metadata_payload = {
            "package": package_metadata(),
            "config_snapshot": config_snapshot(resolved_config),
            "model_metadata": {
                "patient_summarizer": metadata["model_metadata"],
            },
        }
        if return_qc:
            return summaries, metadata_payload, qc_report
        return summaries, metadata_payload
    if return_qc:
        return summaries, qc_report
    return summaries