Skip to content

Trials

matchminer_ai.trials

Trial summarization APIs.

summarize_trials

summarize_trials(trials: DataFrame, *, config: MMAIConfig | 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 clinical trials into clinical spaces and general exclusion criteria.

Parameters:

Name Type Description Default
trials DataFrame

Trial-level input. One row per trial.

Expected columns

trial_id : str Unique trial identifier. trial_title : str Human-readable trial title. brief_summary : str Brief textual summary of the trial. eligibility_criteria : str Full eligibility criteria text for the trial.

required
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

Clinical-space-level DataFrame. One row per clinical space per trial.

Columns

space_trial_id : str Unique identifier for a specific trial + clinical space combination. trial_id : str Original trial identifier (copied through from input). clinical_space_number : int Integer index of the clinical space within the trial. clinical_space_summary : str Summary of the clinical space (disease context, line of therapy, etc). general_exclusion_criteria : str General trial-level exclusion criteria text extracted for this space.

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


trial_input_text : str Concatenation of trial_title + brief_summary + eligibility_criteria. This is the raw input text fed into the LLM. trial_answer_text : str Text the package treated as the LLM answer and used for postprocessing. trial_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/trials/__init__.py
 15
 16
 17
 18
 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
149
150
151
152
153
154
def summarize_trials(
    trials: pd.DataFrame,
    *,
    config: MMAIConfig | 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 clinical trials into clinical spaces and general exclusion criteria.

    Parameters
    ----------
    trials : pd.DataFrame
        Trial-level input. One row per trial.

        Expected columns
        ----------------
        trial_id : str
            Unique trial identifier.
        trial_title : str
            Human-readable trial title.
        brief_summary : str
            Brief textual summary of the trial.
        eligibility_criteria : str
            Full eligibility criteria text for the trial.
    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
        Clinical-space-level DataFrame. One row per clinical space per trial.

        Columns
        -------
        space_trial_id : str
            Unique identifier for a specific trial + clinical space combination.
        trial_id : str
            Original trial identifier (copied through from input).
        clinical_space_number : int
            Integer index of the clinical space within the trial.
        clinical_space_summary : str
            Summary of the clinical space (disease context, line of therapy, etc).
        general_exclusion_criteria : str
            General trial-level exclusion criteria text extracted for this space.

        Debug Columns
        (Available only if pipeline initialized with debug_mode=True)
        -------------------------------------------------------------
        trial_input_text : str
            Concatenation of trial_title + brief_summary + eligibility_criteria.
            This is the raw input text fed into the LLM.
        trial_answer_text : str
            Text the package treated as the LLM answer and used for
            postprocessing.
        trial_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.
    """
    from matchminer_ai.config import MMAIConfig, load_default_preset

    from .postprocess import postprocess_trial_summaries
    from .summarize import run_llm_summarization

    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 = {
        "trial_id",
        "trial_title",
        "brief_summary",
        "eligibility_criteria",
    }
    missing = required_columns.difference(trials.columns)
    if missing:
        missing_list = ", ".join(sorted(missing))
        raise ValueError(
            f"summarize_trials requires columns: {', '.join(sorted(required_columns))}. "
            f"Missing: {missing_list}."
        )

    logger.info("Starting trial summarization for %d trials.", len(trials))
    (
        trials_with_summaries,
        metadata,
        truncated_llm_qc_artifact,
        failed_llm_qc_artifact,
    ) = run_llm_summarization(trials, resolved_config)
    logger.info("Completed LLM summarization. Beginning postprocessing.")
    # Capture unfiltered spaces for QC before keyword filtering.
    result, unfiltered_spaces = postprocess_trial_summaries(
        trials_with_summaries,
        resolved_config,
    )
    logger.info("Postprocessing complete. Produced %d rows.", len(result))

    # Build QC report
    from matchminer_ai._qc.trials import trial_qc_report

    qc_report = trial_qc_report(
        result,
        trial_source=trials,
        unfiltered_spaces=unfiltered_spaces,
        truncated_llm_qc_artifact=truncated_llm_qc_artifact,
        failed_llm_qc_artifact=failed_llm_qc_artifact,
        config=resolved_config,
    )

    # Depending on flags, decide what to return
    if return_metadata:
        metadata_payload = {
            "package": package_metadata(),
            "config_snapshot": config_snapshot(resolved_config),
            "model_metadata": {
                "trial_summarizer": metadata["model_metadata"],
            },
        }
        if return_qc:
            return result, metadata_payload, qc_report
        return result, metadata_payload
    if return_qc:
        return result, qc_report
    return result