Skip to content

Final boehringer fall25#919

Open
souvik2019 wants to merge 10 commits intoopenpharma:mainfrom
souvik2019:FINAL_BOEHRINGER_FALL25
Open

Final boehringer fall25#919
souvik2019 wants to merge 10 commits intoopenpharma:mainfrom
souvik2019:FINAL_BOEHRINGER_FALL25

Conversation

@souvik2019
Copy link

@souvik2019 souvik2019 commented Dec 5, 2025

Pull Request

All changes are made inside the R folder

Design-methods.R

Changes Summary

  • Enhanced simulate() method for CRM designs:
    • Added tracking of cohort-level probabilities for recommended doses.
    • Introduced cohort_probs_df to store probabilities (UD, TD, OD) per cohort.
    • Updated simulation output to include cohort_probs in the returned Simulations object.
  • Improved transparency of dose recommendation logic by exposing intermediate probabilities.
  • Maintained backward compatibility; no changes to existing arguments or core workflow.

Motivation

This update provides users with detailed per-cohort probability information, improving interpretability of dose escalation decisions and supporting more comprehensive reporting.

Impact

  • New Feature: Cohort-level probability summaries.
  • No Breaking Changes: Existing workflows and outputs remain valid.

Rules-class.R

TL;DR

  • Extends NextBestNCRM by adding an underdose slot and constructor argument.
  • Adds new classes: IncrementsConstantFactor, StoppingDoseStagnation, StoppingMinPatientsMtd, StoppingMinDlts, CohortSizeOrdinal.
  • Keeps other classes and defaults largely unchanged; documentation clarified where needed.

Changes in Detail

1) Next Best Dose Rules

Changed: NextBestNCRM

  • Base: slots = target, overdose, max_overdose_prob; constructor expects (target, overdose, max_overdose_prob).
  • PR: adds underdose slot and argument; default underdose = c(0, 0.2).
  • Constructor now: NextBestNCRM(underdose, target, overdose, max_overdose_prob).
  • Default constructor updated to include underdose.

2) Increment Control

New: IncrementsConstantFactor

  • Slots: factor (esc. multiplier), max_dose (cap).
  • Prototype defaults: factor = 3.3, max_dose = 75.
  • Constructor: IncrementsConstantFactor(factor = 3.3, max_dose = 75).

3) Stopping Rules

New:

  • StoppingDoseStagnation: stop when current and recommended doses are the same (check = TRUE).
  • StoppingMinPatientsMtd: stop when ≥ nPatientsMtd have been dosed at MTD (default 6L).
  • StoppingMinDlts: stop when ≥ nDlts DLTs occur (default 1L).

Note: The default for StoppingCohortsNearDose uses percentage = 0.2 while docs define 0–100; confirm whether this is intended as 0.2% or 20%.

4) Cohort Size Rules

New: CohortSizeOrdinal

  • Slots: grade (integer), rule (CohortSize).
  • Default prototype: grade = 1L, rule = CohortSizeRange(intervals = c(0, 30), cohort_size = c(1L, 3L)).

Backward Compatibility & Migration

  • Breaking surface: NextBestNCRM constructor signature changes.
    • Old: NextBestNCRM(target, overdose, max_overdose_prob)
    • New: NextBestNCRM(underdose, target, overdose, max_overdose_prob)
    • Mitigation: Update callers to include underdose = c(0, 0.2) (or study-specific interval).

Examples (PR):

# Updated NextBestNCRM usage:
NextBestNCRM(
  underdose = c(0, 0.2),
  target = c(0.2, 0.35),
  overdose = c(0.35, 1),
  max_overdose_prob = 0.25
)

# New increment rule:
inc_cf <- IncrementsConstantFactor(factor = 3.3, max_dose = 75)

# New stopping rules:
stop_same <- StoppingDoseStagnation(check = TRUE)
stop_mtd  <- StoppingMinPatientsMtd(nPatientsMtd = 6L)
stop_dlts <- StoppingMinDlts(nDlts = 1L)


## Rules-method.R

### TL;DR
- **NextBest NCRM extended**: new `underdose` interval (classes) and underdose probability (methods & output).
- **New classes**: `IncrementsConstantFactor`, `StoppingDoseStagnation`, `StoppingMinPatientsMtd`, `StoppingMinDlts`, `CohortSizeOrdinal`.
- **New methods**: `maxDose(IncrementsConstantFactor)`, `stopTrial()` implementations for the three new stopping rules.
- **Minor bounds adjustments** in NCRM and `StoppingTargetProb`.
- **All other rules/methods unchanged**; documentation clarified.

---

### 1) NextBest Dose Rules
**Changed:** `NextBestNCRM`
- **Slots:** Added `underdose` (numeric interval).  
  Defaults: `underdose = c(0, 0.2)`, `target = c(0.2, 0.35)`, `overdose = c(0.35, 1)`, `max_overdose_prob = 0.25`.
- **Constructor:** Now `NextBestNCRM(underdose, target, overdose, max_overdose_prob)`.
- **Default constructor** updated to include `underdose`.

### 2) Increment Control
**New:** `IncrementsConstantFactor`
- **Slots:** `factor` (numeric escalation multiplier), `max_dose` (cap).
- **Prototype:** `factor = 3.3`, `max_dose = 75`.
- **Constructor:** `IncrementsConstantFactor(factor = 3.3, max_dose = 75)`.

### 3) Stopping Rules
**New:**  
- `StoppingDoseStagnation`stop if current and recommended doses are same.  
- `StoppingMinPatientsMtd`stop when`nPatientsMtd` dosed at MTD (default `6L`).  
- `StoppingMinDlts`stop when`nDlts` DLTs observed (default `1L`).

> Note: `StoppingCohortsNearDose` default uses `percentage = 0.2` while docs define 0100; confirm semantics (0.2% vs 20%).


---

### 4) `nextBest` for `NextBestNCRM`
**PR updates:**
- Computes and returns **`prob_underdose`**:
**Examples (PR):**
```r
  prob_underdose <- colMeans(h_in_range(prob_samples, nextBest@underdose, bounds_closed = c(TRUE, FALSE)))

## Rules-validity.R

- Added **two new internal validators** under the `v_stopping` family:
  - `v_stopping_min_patients_mtd()`checks `StoppingMinPatientsMtd@nPatientsMtd` is a **positive integer scalar**.
  - `v_stopping_min_dlts()`checks `StoppingMinDlts@nDlts` is a **nonnegative integer scalar**.


## Simulations-class.R

Added cohort_probs as a new slot and object, everytime after additional_stats object, in Simulations class

## helpers_design.R

Added cohort_probs as a new slot and object, everytime after additional_stats object

## Model-class.R

- **K-component mixtures** in `LogisticNormalMixture` (previously 2 only).
- **Dirichlet weight priors** with flexible parameterization:
  - Direct `weightpars` OR derive from `prior_weights` + `M` (concentration).
- Extended examples for **fixed mixtures** (`LogisticNormalFixedMixture`) with arbitrary K.

## Key Differences vs Main
- **Main**: Supports 2-component mixture with Beta prior on weight.
- **Fork**: Generalized to K2, Dirichlet weights, optional prior mode specification.
- Added sampling of weights + component index for diagnostics.

## Why Needed
- BI Phase-1 designs require multi-modal priors (dominant weakly-informative + low/high toxicity modes).
- Aligns with internal BLRM conventions for robust escalation decisions.

## Example (K-component mixture)
```r
model <- LogisticNormalMixture(
  components = list(
    ModelParamsNormal(mean = c(-1.28,-0.58), cov = diag(c(4,1))),
    ModelParamsNormal(mean = c(0.31,-0.79),  cov = diag(c(4,1))),
    ModelParamsNormal(mean = c(-4.16,-0.96), cov = matrix(c(25,0,0,1e-4),2))
  ),
  prior_weights = c(0.90,0.05,0.05), M = 20,
  ref_dose = 40
)

## Model-validity.R

- **K-component LogisticNormalMixture** validation:
  - Checks `components` list for valid `ModelParamsNormal` or equivalent structure.
  - Ensures `weightpars` is a positive numeric vector of length K (Dirichlet parameters).
  - Optional `ref_dose` validation.
- **Backward compatibility**: Old Beta-based check replaced with generalized Dirichlet validation.

## Key Differences vs Main
- **Main**: Validates only 2-component mixture with Beta(a,b) prior.
- **Fork**: Supports K2 components, Dirichlet weights, and optional prior mode-based parameterization.
- Added checks for:
  - Positive-definite covariance/precision matrices.
  - Minimum component count (≥ 2).
  - Flexible input (S4 or plain list with mean/cov/prec).

## Why Needed
- BI designs require multi-modal priors with explicit weight control.
- Validation ensures robustness for extended mixture functionality.

## Example (Validation Logic)
```r
# Fork: v_model_logistic_normal_mix
v$check(test_numeric(object@weightpars, len = k),
        "weightpars must be positive, finite, length = components")
v$check(k >= 2, "components must contain at least two mixture components")


@souvik2019
Copy link
Author

Added a few changes. Please review.

@danielinteractive
Copy link
Collaborator

thanks a lot @souvik2019 ! lots of stuff, cool.
Any chance you have any tests for these additions too? Just checking.

Adding prior for weights for k comp mixture
Added validity check related to prior of k components
@souvik2019 souvik2019 marked this pull request as draft December 5, 2025 23:54
@souvik2019
Copy link
Author

thanks a lot @souvik2019 ! lots of stuff, cool. Any chance you have any tests for these additions too? Just checking.

Hi Daniel,
Thank you for your response. I have just added another (which i forgot) two commits for priors in normal mixture for more than two components.

Regarding the test, we have tested it and these works. How do you want me to provide the tests? Will it be a pdf or html or any other format?
Thank you very much.

@souvik2019 souvik2019 marked this pull request as ready for review December 6, 2025 02:02
@souvik2019 souvik2019 marked this pull request as draft December 6, 2025 02:19
@souvik2019 souvik2019 marked this pull request as ready for review December 6, 2025 02:20
@danielinteractive
Copy link
Collaborator

Dear @souvik2019 ,

thanks a lot, that is great!

Ideally, you could create (sequentially, not all at once) PRs for each topic, with associated unit tests. You can have a look in the tests/testthat folder for the structure within each file, there are always strong patterns within these test files which you can follow.

Where it depends on the choice (e.g. whether a bound is inclusive or exclusive for the target toxicity interval, just as an example) it would be best to 1) introduce an argument which allows to make the choice and 2) to keep the default behavior as it currently is for backwards compatibility for the general users.

You can still keep the overall PR as a collection of the overall work to be done, but for code review and tests production etc. it would be much better to have individual topic focused PRs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants