Files

1620 lines
57 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
title: "Clinical Trial Design Feasibility Examples"
task: ""
lineage_type: import
upstream_source: https://github.com/mims-harvard/ToolUniverse/blob/e2520a96/skills/tooluniverse-clinical-trial-design/EXAMPLES.md
upstream_sha: e2520a96
imported_at: 2026-06-26
prompt_class: prompt
upstream_changes: accepted
author: upstream
validated: false
---
# Clinical Trial Design Feasibility Examples
Concrete examples of trial feasibility assessments using ToolUniverse.
---
## Example 1: Biomarker-Selected Oncology Trial (EGFR+ NSCLC)
**Scenario**: Assess feasibility of Phase 1/2 trial for novel EGFR inhibitor in EGFR L858R+ NSCLC patients who progressed on osimertinib.
### Setup
```python
from tooluniverse import ToolUniverse
tu = ToolUniverse(use_cache=True)
tu.load_tools()
# Trial parameters
indication = "EGFR L858R+ non-small cell lung cancer, osimertinib-resistant"
phase = "Phase 1/2"
primary_endpoint = "Objective Response Rate (ORR)"
biomarker = "EGFR L858R"
```
### Step 1: Patient Population Sizing
```python
# 1.1: Get disease prevalence
disease_info = tu.tools.OpenTargets_get_disease_id_description_by_name(
diseaseName="non-small cell lung cancer"
)
print(f"Disease: {disease_info['data']['name']}")
print(f"EFO ID: {disease_info['data']['id']}")
# Get phenotype/prevalence data
phenotypes = tu.tools.OpenTargets_get_diseases_phenotypes(
efoId=disease_info['data']['id']
)
# 1.2: Get biomarker prevalence from ClinVar
egfr_variants = tu.tools.ClinVar_search_variants(
gene="EGFR",
significance="pathogenic,likely_pathogenic"
)
# Filter to L858R
l858r_variants = [v for v in egfr_variants['data']
if 'L858R' in v.get('name', '')]
print(f"\nEGFR L858R variants found: {len(l858r_variants)}")
# 1.3: Cross-reference with population genetics
gnomad_egfr = tu.tools.gnomad_search_variants(
gene="EGFR"
)
# Filter to L858R (c.2573T>G)
l858r_gnomad = [v for v in gnomad_egfr['data']
if v.get('hgvs_c', '').startswith('c.2573T>G')]
# 1.4: Search literature for epidemiology
epi_papers = tu.tools.PubMed_search_articles(
query="EGFR L858R prevalence NSCLC epidemiology United States Asia",
max_results=30
)
print(f"\nEpidemiology papers found: {len(epi_papers['data'])}")
# Extract key papers
key_epi_papers = []
for paper in epi_papers['data'][:5]:
key_epi_papers.append({
'title': paper.get('title'),
'pmid': paper.get('pmid'),
'year': paper.get('pub_year')
})
# 1.5: Calculate patient availability
# From literature: NSCLC ~200K/year US, EGFR+ 15%, L858R 45% of EGFR+
us_nsclc_annual = 200000
egfr_positive_rate = 0.15
l858r_within_egfr = 0.45
l858r_annual = us_nsclc_annual * egfr_positive_rate * l858r_within_egfr
print(f"\nEstimated L858R+ NSCLC patients/year (US): {l858r_annual:.0f}")
# For osimertinib-resistant: assume ~80% progress on osimertinib
osimertinib_resistant = l858r_annual * 0.80
print(f"Osimertinib-resistant L858R+ patients/year: {osimertinib_resistant:.0f}")
# Apply eligibility criteria
eligibility_factors = {
'age_18_75': 0.85,
'ecog_0_1': 0.70,
'adequate_organ': 0.90,
'measurable_disease': 0.75,
'no_brain_mets': 0.60
}
eligible_pool = osimertinib_resistant
for criterion, factor in eligibility_factors.items():
eligible_pool *= factor
print(f" After {criterion}: {eligible_pool:.0f} ({factor*100:.0f}%)")
print(f"\nFinal eligible pool: {eligible_pool:.0f} patients/year")
# Enrollment projection for N=50
target_n = 50
sites = 15
capture_rate = 0.03 # 3% of eligible patients
monthly_enrollment = (eligible_pool * capture_rate) / 12 / sites
print(f"\nTarget enrollment: {target_n}")
print(f"Sites: {sites}")
print(f"Patients per site per month: {monthly_enrollment:.2f}")
print(f"Enrollment timeline: {target_n / (monthly_enrollment * sites):.1f} months")
```
**Expected Output**:
```
Disease: non-small cell lung cancer
EFO ID: EFO_0003060
EGFR L858R variants found: 12
Epidemiology papers found: 28
Estimated L858R+ NSCLC patients/year (US): 13500
Osimertinib-resistant L858R+ patients/year: 10800
After age_18_75: 9180 (85%)
After ecog_0_1: 6426 (70%)
After adequate_organ: 5783 (90%)
After measurable_disease: 4338 (75%)
After no_brain_mets: 2603 (60%)
Final eligible pool: 2603 patients/year
Target enrollment: 50
Sites: 15
Patients per site per month: 0.43
Enrollment timeline: 7.7 months
```
### Step 2: Biomarker Testing Strategy
```python
# 2.1: Search for FDA-approved companion diagnostics
cdx_papers = tu.tools.PubMed_search_articles(
query="FDA approved companion diagnostic EGFR L858R liquid biopsy",
max_results=20
)
print("FDA-approved CDx landscape:")
for paper in cdx_papers['data'][:5]:
print(f" - {paper.get('title')} (PMID: {paper.get('pmid')})")
# 2.2: Literature on testing turnaround time
tat_papers = tu.tools.PubMed_search_articles(
query="EGFR mutation testing turnaround time NGS liquid biopsy",
max_results=15
)
# From literature: NGS turnaround 7-14 days, liquid biopsy 7-10 days
testing_strategy = {
'primary_method': 'NGS (tissue)',
'turnaround': '10-14 days',
'cost': '$500-800',
'alternative': 'Liquid biopsy (ctDNA)',
'alternative_tat': '7-10 days',
'alternative_cost': '$300-500'
}
print(f"\nRecommended biomarker testing:")
for key, value in testing_strategy.items():
print(f" {key}: {value}")
```
### Step 3: Comparator Selection
```python
# 3.1: Get standard of care info (osimertinib)
comparator = "osimertinib"
comparator_info = tu.tools.drugbank_get_drug_basic_info_by_drug_name_or_id(
drug_name_or_drugbank_id=comparator
)
comparator_indications = tu.tools.drugbank_get_indications_by_drug_name_or_drugbank_id(
drug_name_or_drugbank_id=comparator
)
print(f"\nComparator: {comparator}")
print(f"Status: {comparator_info['data']['groups']}")
print(f"Indications: {len(comparator_indications['data'])}")
# 3.2: Get FDA approval details
fda_approval = tu.tools.OpenFDA_get_approval_history(
drug_name=comparator
)
if fda_approval and 'data' in fda_approval:
for approval in fda_approval['data'][:3]:
print(f"\n Approval: {approval.get('date', 'N/A')}")
print(f" Indication: {approval.get('indication', 'N/A')}")
# 3.3: Find historical control data from clinical trials
historical_trials = tu.tools.search_clinical_trials(
condition="EGFR positive non-small cell lung cancer",
intervention=comparator,
status="completed",
phase="2|3"
)
print(f"\n{comparator} trials found: {len(historical_trials['data'])}")
# Extract ORR data from key trials
for trial in historical_trials['data'][:3]:
print(f"\n NCT: {trial.get('nct_number')}")
print(f" Title: {trial.get('title')}")
print(f" Status: {trial.get('status')}")
# Note: Would parse results for ORR in real analysis
# 3.4: Single-arm vs. randomized design decision
print("\n" + "="*80)
print("COMPARATOR ANALYSIS SUMMARY")
print("="*80)
print(f"Standard of Care: {comparator} (FDA approved)")
print(f"Historical ORR: ~50-60% in osimertinib-naive, ~30% in T790M-resistant")
print(f"Comparator availability: Commercial supply available")
print(f"\nDesign recommendation: SINGLE-ARM PHASE 2")
print(f"Rationale:")
print(f" - Robust historical control data available (multiple trials)")
print(f" - Patient population narrowly defined (L858R, osimertinib-resistant)")
print(f" - Faster enrollment (no randomization)")
print(f" - Lower cost")
print(f" - Acceptable for Phase 2; randomized Phase 3 if successful")
```
### Step 4: Endpoint Selection
```python
# 4.1: Search for precedent trials using ORR
orr_precedent = tu.tools.search_clinical_trials(
condition="EGFR positive non-small cell lung cancer",
phase="2",
status="completed"
)
orr_trials_count = 0
pfs_trials_count = 0
for trial in orr_precedent['data']:
primary_outcome = trial.get('primary_outcome', '').lower()
if 'response rate' in primary_outcome or 'orr' in primary_outcome:
orr_trials_count += 1
if 'progression' in primary_outcome or 'pfs' in primary_outcome:
pfs_trials_count += 1
print("PRIMARY ENDPOINT ANALYSIS")
print("="*80)
print(f"Phase 2 trials in EGFR+ NSCLC: {len(orr_precedent['data'])}")
print(f" - Using ORR as primary: {orr_trials_count}")
print(f" - Using PFS as primary: {pfs_trials_count}")
# 4.2: FDA approval precedents using ORR
orr_approval_papers = tu.tools.PubMed_search_articles(
query="FDA approval objective response rate NSCLC EGFR inhibitor accelerated",
max_results=25
)
print(f"\nFDA approval papers with ORR: {len(orr_approval_papers['data'])}")
# Sample key approvals (from literature/knowledge):
fda_orr_approvals = [
{'drug': 'osimertinib', 'year': 2015, 'orr': '57%', 'n': 411, 'indication': 'T790M+'},
{'drug': 'dacomitinib', 'year': 2018, 'orr': '75%', 'n': 452, 'indication': '1L EGFR+'},
{'drug': 'mobocertinib', 'year': 2021, 'orr': '28%', 'n': 114, 'indication': 'exon20ins'}
]
print("\nFDA Approvals Using ORR (EGFR+ NSCLC):")
for approval in fda_orr_approvals:
print(f" {approval['drug']} ({approval['year']}): ORR {approval['orr']}, n={approval['n']}")
# 4.3: Statistical design for ORR
print("\n" + "="*80)
print("RECOMMENDED PRIMARY ENDPOINT: Objective Response Rate (ORR)")
print("="*80)
print("Evidence Grade: ★★★ (Regulatory precedent, multiple approvals)")
print("\nJustification:")
print(" 1. FDA-accepted for accelerated approval in EGFR+ NSCLC")
print(" 2. Feasible in Phase 2 (rapid readout, smaller N)")
print(" 3. Clinically meaningful (patient benefit)")
print(" 4. Standard assessment (RECIST 1.1, CT imaging)")
print("\nStatistical Design (Simon 2-stage):")
print(" - Null hypothesis (H0): ORR ≤ 15% (below clinically meaningful)")
print(" - Target ORR (H1): ORR ≥ 35% (clinically significant improvement)")
print(" - Alpha: 0.05 (one-sided), Beta: 0.20 (80% power)")
print(" - Stage 1: Enroll 13 patients")
print(" → If ≥ 2 responses, proceed to Stage 2")
print(" → If < 2 responses, stop for futility")
print(" - Stage 2: Enroll 30 additional patients (N=43 total)")
print(" → Declare success if ≥ 11 responses overall (ORR ≥ 25.6%)")
print("\nSecondary Endpoints:")
print(" - Duration of Response (DoR)")
print(" - Progression-Free Survival (PFS)")
print(" - Overall Survival (OS, with long-term follow-up)")
print(" - Safety (AEs per CTCAE v5.0)")
print("\nExploratory Endpoints:")
print(" - ctDNA clearance (liquid biopsy)")
print(" - Biomarkers of resistance (T790M acquisition, C797S)")
print(" - Quality of life (EORTC QLQ-C30)")
```
### Step 5: Safety Monitoring
```python
# 5.1: Get class effect toxicities from similar EGFR inhibitors
reference_drug = "erlotinib" # Earlier-generation EGFR TKI
reference_pharmacology = tu.tools.drugbank_get_pharmacology_by_drug_name_or_drugbank_id(
drug_name_or_drugbank_id=reference_drug
)
reference_warnings = tu.tools.FDA_get_warnings_and_cautions_by_drug_name(
drug_name=reference_drug
)
print("SAFETY MONITORING PLAN")
print("="*80)
print(f"Reference drug for class effects: {reference_drug}")
print(f"FDA warnings: {len(reference_warnings.get('data', []))}")
# 5.2: FAERS data for real-world AEs
faers_egfr = tu.tools.FAERS_search_reports_by_drug_and_reaction(
drug_name=reference_drug,
limit=1000
)
ae_counts = tu.tools.FAERS_count_reactions_by_drug_event(
medicinalproduct=reference_drug.upper()
)
print(f"\nFAERS reports for {reference_drug}: {len(faers_egfr.get('data', []))}")
print("\nTop 10 Adverse Events (FAERS):")
for i, ae in enumerate(ae_counts.get('results', [])[:10], 1):
print(f" {i}. {ae['term']}: {ae['count']} reports")
# 5.3: Define mechanism-based toxicity monitoring
print("\n" + "="*80)
print("MECHANISM-BASED TOXICITY MONITORING")
print("="*80)
toxicity_monitoring = {
'Dermatologic': {
'toxicities': ['Rash (acneiform)', 'Dry skin', 'Paronychia'],
'incidence': '60-80% (any grade), 10-15% (Grade 3+)',
'monitoring': 'Dermatology assessment q cycle, patient diary',
'management': 'Topical steroids, doxycycline, dose modification'
},
'Gastrointestinal': {
'toxicities': ['Diarrhea', 'Nausea', 'Decreased appetite'],
'incidence': '50-60% (any grade), 5-10% (Grade 3+)',
'monitoring': 'Symptom diary, electrolytes if Grade 2+',
'management': 'Loperamide, hydration, dose hold if Grade 3+'
},
'Hepatic': {
'toxicities': ['ALT/AST elevation', 'Hyperbilirubinemia'],
'incidence': '20-30% (any grade), 3-5% (Grade 3+)',
'monitoring': 'LFTs weekly (Cycle 1), then q3 weeks',
'management': 'Dose hold if ALT >5× ULN, discontinue if Hy\'s Law'
},
'Pulmonary': {
'toxicities': ['Interstitial lung disease (ILD)', 'Pneumonitis'],
'incidence': '1-3% (any grade), 0.5-1% (Grade 3+)',
'monitoring': 'CT chest at baseline, q12 weeks; symptoms q visit',
'management': 'Discontinue if ILD, systemic steroids'
}
}
for organ, details in toxicity_monitoring.items():
print(f"\n{organ}:")
for key, value in details.items():
if key == 'toxicities':
print(f" {key}: {', '.join(value)}")
else:
print(f" {key}: {value}")
# 5.4: DLT definition (Phase 1 component)
print("\n" + "="*80)
print("DOSE-LIMITING TOXICITY (DLT) DEFINITION - PHASE 1")
print("="*80)
print("Assessment Period: Cycle 1 (28 days)")
print("\nDLTs include:")
print(" - Grade ≥3 non-hematologic toxicity (except manageable with Rx)")
print(" - Grade 4 hematologic toxicity >7 days")
print(" - Any toxicity causing >2 week dose delay in Cycle 1")
print(" - Any Grade 5 (death) related to study drug")
print("\nExceptions (NOT considered DLTs):")
print(" - Grade 3 rash if resolves to ≤Grade 1 within 7 days with treatment")
print(" - Grade 3 diarrhea if resolves within 2 days with loperamide")
print(" - Grade 3 nausea/vomiting if controlled with antiemetics")
print("\nDose Escalation Design: 3+3")
print(" Starting dose: [X] mg QD (10% predicted human efficacious dose)")
print(" Dose levels: [X], [1.5X], [2X], [3X] mg QD")
print(" Rule: ≥2 DLTs at a level → MTD exceeded; previous level is MTD")
```
### Step 6: Regulatory Pathway
```python
# 6.1: Search for breakthrough therapy designations
bt_papers = tu.tools.PubMed_search_articles(
query="FDA breakthrough therapy designation NSCLC EGFR inhibitor",
max_results=20
)
print("REGULATORY PATHWAY ANALYSIS")
print("="*80)
print(f"Breakthrough therapy papers: {len(bt_papers['data'])}")
# 6.2: Check orphan drug eligibility
us_prevalence = osimertinib_resistant # From Step 1: ~10,800/year
print(f"\nOrphan Drug Designation Eligibility:")
print(f" Indication: EGFR L858R+ NSCLC, osimertinib-resistant")
print(f" Estimated US patients: {us_prevalence:.0f}/year")
print(f" Orphan threshold: <200,000 total prevalence")
print(f" Assessment: LIKELY NOT ELIGIBLE (too prevalent)")
# 6.3: FDA guidance documents
guidance_papers = tu.tools.PubMed_search_articles(
query="FDA guidance clinical trial endpoints NSCLC oncology",
max_results=15
)
print(f"\nFDA guidance documents: {len(guidance_papers['data'])} papers")
# 6.4: Regulatory recommendations
print("\n" + "="*80)
print("RECOMMENDED REGULATORY STRATEGY")
print("="*80)
print("\nPathway: 505(b)(1) (New Drug Application)")
print(" - Novel molecular entity")
print(" - No published safety data to rely on")
print("\nPotential Designations:")
print(" 1. Breakthrough Therapy [POSSIBLE]")
print(" Criteria: Preliminary evidence of substantial improvement")
print(" Threshold: ORR >50% in osimertinib-resistant (vs. ~10-15% SOC)")
print(" Benefit: Rolling NDA submission, frequent FDA meetings")
print(" Timing: Apply after Phase 1/2a data (n≥20, ORR clear)")
print("\n 2. Fast Track [LIKELY]")
print(" Criteria: Treats serious condition, addresses unmet need")
print(" Benefit: Rolling review, more frequent FDA interaction")
print(" Timing: Apply at IND or early Phase 1")
print("\n 3. Accelerated Approval [TARGET]")
print(" Endpoint: ORR (surrogate for OS)")
print(" Requirement: Confirmatory Phase 3 trial (OS primary)")
print(" Timing: After positive Phase 2 (ORR ≥35%, n=43)")
print("\nRegulatory Milestones:")
print(" Month -4: Pre-IND meeting request")
print(" Month -3: Pre-IND meeting (discuss endpoint, design)")
print(" Month 0: IND submission")
print(" Month 1: First patient dosed (if no clinical hold)")
print(" Month 9: Phase 1 complete, RP2D determined")
print(" Month 16: Phase 2 interim (Simon Stage 1, n=13)")
print(" Month 24: Phase 2 complete (n=43)")
print(" Month 27: End-of-Phase 2 meeting, Phase 3 design discussion")
```
### Final Feasibility Report Generation
```python
# Compile all data into feasibility score
print("\n" + "="*80)
print("FEASIBILITY SCORECARD")
print("="*80)
dimensions = {
'Patient Availability': {
'weight': 0.30,
'raw_score': 8, # 8/10
'evidence': '★★★',
'rationale': '~2,600 eligible/year, 7.7-month enrollment for n=50'
},
'Endpoint Precedent': {
'weight': 0.25,
'raw_score': 9, # 9/10
'evidence': '★★★',
'rationale': 'ORR accepted for accelerated approval, 10+ precedents'
},
'Regulatory Clarity': {
'weight': 0.20,
'raw_score': 8, # 8/10
'evidence': '★★☆',
'rationale': 'Clear 505(b)(1) path, breakthrough potential, pre-IND advised'
},
'Comparator Feasibility': {
'weight': 0.15,
'raw_score': 9, # 9/10
'evidence': '★★★',
'rationale': 'Robust historical data (osimertinib ORR 30-60%), single-arm viable'
},
'Safety Monitoring': {
'weight': 0.10,
'raw_score': 8, # 8/10
'evidence': '★★☆',
'rationale': 'EGFR TKI class effects well-characterized, manageable'
}
}
feasibility_score = 0
print(f"{'Dimension':<30} {'Weight':<10} {'Score':<10} {'Weighted':<10} {'Evidence':<10}")
print("-" * 80)
for dimension, data in dimensions.items():
weighted = data['weight'] * data['raw_score'] * 10
feasibility_score += weighted
print(f"{dimension:<30} {data['weight']*100:.0f}%{'':<7} "
f"{data['raw_score']}/10{'':<5} "
f"{weighted:.1f}{'':<7} "
f"{data['evidence']:<10}")
print(f" Rationale: {data['rationale']}")
print("-" * 80)
print(f"{'TOTAL FEASIBILITY SCORE':<30} {'100%':<10} {'':<10} "
f"{feasibility_score:.0f}/100{'':<7} {'HIGH':<10}")
print("\n" + "="*80)
print("FINAL RECOMMENDATION: RECOMMEND PROCEED")
print("="*80)
print("""
This Phase 1/2 trial demonstrates HIGH feasibility (Score: 82/100).
Key Strengths:
1. Patient availability is strong with ~2,600 eligible patients/year
2. ORR is FDA-accepted with robust regulatory precedent
3. Single-arm design is defensible with strong historical control data
4. Safety monitoring is well-established for EGFR TKI class
Critical Path:
1. Pre-IND meeting (Month -3) to confirm single-arm design acceptability
2. Secure CDx partnership for EGFR testing (liquid biopsy preferred)
3. IND submission (Month 0)
4. First patient dosed (Month 1)
5. Phase 2 interim analysis (Month 16, Simon Stage 1)
6. Phase 2 completion (Month 24, n=43)
Key Risk: Screen failure rate may be higher if liquid biopsy false-negative
Mitigation: Tissue re-biopsy for liquid biopsy-negative but clinically suspected
Budget Estimate: $3.5-5.0M (Phase 1/2 combined, 15 sites)
Timeline: 24 months (first patient to primary analysis)
""")
```
---
## Example 2: Rare Disease Trial (Niemann-Pick Type C)
**Scenario**: Assess feasibility of Phase 2 trial for novel cholesterol transport modifier in Niemann-Pick Type C (NPC), a lysosomal storage disorder with prevalence ~1:120,000.
### Setup
```python
from tooluniverse import ToolUniverse
tu = ToolUniverse(use_cache=True)
tu.load_tools()
indication = "Niemann-Pick Type C"
phase = "Phase 2"
primary_endpoint = "Change in NPC Clinical Severity Score"
```
### Step 1: Ultra-Rare Disease Population Sizing
```python
# 1.1: Search OpenTargets
disease_info = tu.tools.OpenTargets_get_disease_id_description_by_name(
diseaseName="Niemann-Pick disease type C"
)
print(f"Disease: {disease_info['data']['name']}")
print(f"Description: {disease_info['data']['description'][:200]}...")
# 1.2: Literature for prevalence
prevalence_papers = tu.tools.PubMed_search_articles(
query="Niemann-Pick type C prevalence incidence epidemiology",
max_results=30
)
print(f"\nPrevalence papers: {len(prevalence_papers['data'])}")
# From literature: 1:120,000 births
us_population = 330000000
npc_prevalence = us_population / 120000
annual_births_us = 3700000
annual_incidence = annual_births_us / 120000
print(f"\nEstimated US Prevalence:")
print(f" Total NPC patients: {npc_prevalence:.0f}")
print(f" Annual incidence: {annual_incidence:.0f} new cases/year")
# 1.3: Get genetic basis
npc_genes = ["NPC1", "NPC2"]
for gene in npc_genes:
variants = tu.tools.ClinVar_search_variants(
gene=gene,
significance="pathogenic,likely_pathogenic"
)
print(f"\n{gene} pathogenic variants: {len(variants['data'])}")
# 1.4: Eligibility criteria impact (stricter for rare disease)
eligibility_factors = {
'confirmed_genetic_diagnosis': 0.90, # Molecular diagnosis required
'age_5_50': 0.60, # Exclude infantile and very late-onset
'ambulatory': 0.40, # Neurologic impairment common
'no_liver_transplant': 0.85,
'willing_travel': 0.30 # Only specialized centers
}
eligible_pool = npc_prevalence
print(f"\nEligibility Funnel:")
for criterion, factor in eligibility_factors.items():
eligible_pool *= factor
print(f" After {criterion}: {eligible_pool:.0f} ({factor*100:.0f}%)")
print(f"\nFinal eligible pool (US): {eligible_pool:.0f} patients")
print(f" Percentage of total NPC population: {(eligible_pool/npc_prevalence)*100:.1f}%")
# 1.5: Enrollment projection
target_n = 30 # Small N for rare disease
us_sites = 5 # Only specialized centers (NIH, Mayo, etc.)
international_sites = 10 # Need EU sites
total_eligible_global = eligible_pool * 3 # Assume 3× for US+EU+other
months_to_enroll = target_n / (total_eligible_global * 0.20 / 12) # 20% capture
print(f"\nEnrollment Projection:")
print(f" Target N: {target_n}")
print(f" US sites: {us_sites}")
print(f" International sites: {international_sites}")
print(f" Global eligible pool: ~{total_eligible_global:.0f}")
print(f" Estimated enrollment: {months_to_enroll:.1f} months ({months_to_enroll/12:.1f} years)")
print(f" ⚠ CHALLENGE: Multi-year enrollment for small study")
```
**Key Finding**: Enrollment is a MAJOR challenge (36+ months for n=30)
### Step 2: Natural History & Endpoint Selection
```python
# 2.1: Search for natural history studies
nh_papers = tu.tools.PubMed_search_articles(
query="Niemann-Pick type C natural history clinical severity progression",
max_results=40
)
print("ENDPOINT SELECTION FOR RARE DISEASE")
print("="*80)
print(f"Natural history papers: {len(nh_papers['data'])}")
# 2.2: Search for existing clinical trials (learn from precedents)
npc_trials = tu.tools.search_clinical_trials(
condition="Niemann-Pick Disease Type C",
status="completed|active"
)
print(f"\nNPC clinical trials: {len(npc_trials['data'])}")
endpoints_used = {}
for trial in npc_trials['data']:
primary = trial.get('primary_outcome', '')
if primary:
key = primary[:50] # Truncate for grouping
endpoints_used[key] = endpoints_used.get(key, 0) + 1
print("\nEndpoints used in prior NPC trials:")
for endpoint, count in sorted(endpoints_used.items(), key=lambda x: x[1], reverse=True)[:5]:
print(f" - {endpoint}... (n={count} trials)")
# 2.3: Endpoint analysis
print("\n" + "="*80)
print("PRIMARY ENDPOINT ASSESSMENT")
print("="*80)
endpoint_options = [
{
'name': 'NPC Clinical Severity Score (17-domain)',
'evidence_grade': '★★☆',
'pros': 'Validated, used in prior trials, captures multi-organ impact',
'cons': 'Slow progression (need 18-24 month trial), subjective components',
'sample_size': 'n=30 per arm for 2-point change (90% power)',
'feasibility': 'MODERATE (long trial duration)'
},
{
'name': 'Swallowing function (videofluoroscopy)',
'evidence_grade': '★☆☆',
'pros': 'Objective, sensitive to change, clinically meaningful',
'cons': 'Not validated as primary, specialized equipment',
'sample_size': 'n=20 per arm (if validated)',
'feasibility': 'LOW (needs prospective validation)'
},
{
'name': 'Biomarker: plasma oxysterol (7-KC, cholestane-triol)',
'evidence_grade': '★★☆',
'pros': 'Mechanistic, rapid readout, validated in NPC',
'cons': 'Surrogate (not clinical benefit), FDA may not accept for approval',
'sample_size': 'n=15 per arm for 50% reduction',
'feasibility': 'HIGH (short trial, small N)'
}
]
for i, endpoint in enumerate(endpoint_options, 1):
print(f"\nOption {i}: {endpoint['name']} {endpoint['evidence_grade']}")
print(f" Pros: {endpoint['pros']}")
print(f" Cons: {endpoint['cons']}")
print(f" Sample size: {endpoint['sample_size']}")
print(f" Feasibility: {endpoint['feasibility']}")
print("\n" + "="*80)
print("RECOMMENDED ENDPOINT STRATEGY")
print("="*80)
print("Primary: NPC Clinical Severity Score (17-domain)")
print(" - Evidence grade: ★★☆ (used in prior trials)")
print(" - Design: Change from baseline to Month 18")
print(" - Sample size: n=30 (single-arm, vs. natural history)")
print("\nKey Secondary:")
print(" - Biomarker: Plasma oxysterols (7-KC, cholestane-triol)")
print(" - Swallowing function (videofluoroscopy)")
print(" - Ambulation index")
print(" - Quality of life (caregiver-rated)")
print("\n⚠ Challenge: 18-24 month trial duration compounds enrollment challenge")
```
### Step 3: Regulatory Pathway (Orphan Drug)
```python
# 3.1: Orphan drug designation
print("REGULATORY PATHWAY: ORPHAN DRUG")
print("="*80)
print(f"Disease Prevalence: {npc_prevalence:.0f} patients in US")
print(f"Orphan Threshold: <200,000 affected individuals")
print(f"Status: ✓ QUALIFIES for Orphan Drug Designation")
print("\nOrphan Drug Benefits:")
print(" 1. 7-year market exclusivity")
print(" 2. Tax credits for clinical trial costs (25%)")
print(" 3. Waiver of PDUFA fees (~$3M)")
print(" 4. Protocol assistance from FDA")
print(" 5. Expedited review")
# 3.2: Search for orphan drug approvals in similar indications
orphan_papers = tu.tools.PubMed_search_articles(
query="FDA orphan drug approval lysosomal storage disease",
max_results=30
)
print(f"\nOrphan approvals in lysosomal storage: {len(orphan_papers['data'])} papers")
# 3.3: Regulatory precedents
print("\n" + "="*80)
print("REGULATORY PRECEDENTS (Similar Rare Diseases)")
print("="*80)
precedents = [
{
'drug': 'Miglustat (Zavesca)',
'disease': 'Gaucher disease type 1',
'year': 2003,
'endpoint': 'Organ volume reduction',
'design': 'Single-arm (n=28)',
'approval': 'Regular approval (not accelerated)'
},
{
'drug': 'Cerliponase alfa (Brineura)',
'disease': 'CLN2 Batten disease',
'year': 2017,
'endpoint': 'Motor-language score',
'design': 'Single-arm vs. natural history (n=24)',
'approval': 'Regular approval'
}
]
for p in precedents:
print(f"\n{p['drug']} ({p['year']}):")
print(f" Disease: {p['disease']}")
print(f" Endpoint: {p['endpoint']}")
print(f" Design: {p['design']}")
print(f" Approval: {p['approval']}")
print("\n" + "="*80)
print("RECOMMENDATION: Orphan Drug Designation + Natural History Control")
print("="*80)
print("Design: Single-arm Phase 2, n=30")
print("Comparator: Natural history cohort (published data + registry)")
print("Rationale:")
print(" - Ethical concerns with placebo in rare, progressive disease")
print(" - Well-characterized natural history available")
print(" - Regulatory precedent (Cerliponase alfa approved with NH control)")
print("\nKey Risk: FDA may still prefer randomized placebo-controlled")
print("Mitigation: Pre-IND meeting to discuss and gain alignment")
```
### Final Feasibility Assessment
```python
print("\n" + "="*80)
print("FEASIBILITY SCORECARD: NIEMANN-PICK TYPE C TRIAL")
print("="*80)
dimensions = {
'Patient Availability': {
'weight': 0.30,
'raw_score': 3, # 3/10 - MAJOR CHALLENGE
'evidence': '★★★',
'rationale': 'Only ~500 eligible in US, 36+ months enrollment for n=30'
},
'Endpoint Precedent': {
'weight': 0.25,
'raw_score': 6, # 6/10
'evidence': '★★☆',
'rationale': 'Severity score used in trials, but slow progression'
},
'Regulatory Clarity': {
'weight': 0.20,
'raw_score': 8, # 8/10
'evidence': '★★★',
'rationale': 'Clear orphan path, precedents for NH control, FDA supportive'
},
'Comparator Feasibility': {
'weight': 0.15,
'raw_score': 7, # 7/10
'evidence': '★★☆',
'rationale': 'Natural history data available, registries exist'
},
'Safety Monitoring': {
'weight': 0.10,
'raw_score': 7, # 7/10
'evidence': '★☆☆',
'rationale': 'Novel mechanism, some preclinical safety data'
}
}
feasibility_score = sum(d['weight'] * d['raw_score'] * 10 for d in dimensions.values())
print(f"{'Dimension':<30} {'Weight':<10} {'Score':<10} {'Weighted':<10}")
print("-" * 70)
for dimension, data in dimensions.items():
weighted = data['weight'] * data['raw_score'] * 10
print(f"{dimension:<30} {data['weight']*100:.0f}%{'':<7} {data['raw_score']}/10{'':<5} {weighted:.1f}")
print(f" {data['rationale']}")
print("-" * 70)
print(f"TOTAL FEASIBILITY SCORE: {feasibility_score:.0f}/100 - MODERATE-LOW")
print("\n" + "="*80)
print("FINAL RECOMMENDATION: CONDITIONAL GO")
print("="*80)
print("""
This Phase 2 trial demonstrates MODERATE-LOW feasibility (Score: 58/100).
CRITICAL CHALLENGE: Patient recruitment
- Only ~500 eligible patients in US (after eligibility criteria)
- 36-48 months to enroll n=30, even with international sites
- Competing trials and natural history studies reduce available pool
STRENGTHS:
- Clear regulatory path (orphan drug, natural history control accepted)
- Significant unmet need (no approved therapies)
- Supportive patient advocacy and registry infrastructure
REQUIRED DE-RISKING STEPS:
1. Partnership with NPC patient registry (pre-identify patients)
2. Investigator consortium (NIH, Mayo, International NPC Consortium)
3. Pre-IND meeting to confirm natural history comparator acceptability
4. Biomarker enrichment (e.g., focus on NPC1 variants, exclude NPC2)
5. Adaptive design (allow enrollment extension if slow)
ALTERNATIVE DESIGN:
- If enrollment remains infeasible: Expanded Access Protocol
- Collect real-world data for future regulatory submission
- Smaller n=15-20 with biomarker primary endpoint (faster readout)
BUDGET: $5-8M (higher per-patient costs, longer duration)
TIMELINE: 48-60 months (enrollment + follow-up)
""")
```
---
## Example 3: Superiority Trial vs. Standard of Care (Checkpoint Inhibitor)
**Scenario**: Design Phase 2b randomized trial for novel PD-1 inhibitor vs. pembrolizumab in PD-L1 high (TPS ≥50%) NSCLC, first-line.
### Setup
```python
from tooluniverse import ToolUniverse
tu = ToolUniverse(use_cache=True)
tu.load_tools()
indication = "PD-L1 high (TPS ≥50%) non-small cell lung cancer, first-line"
design = "Phase 2b, randomized 1:1"
primary_endpoint = "Objective Response Rate (ORR)"
comparator = "pembrolizumab"
```
### Step 1: Patient Population (Biomarker-Selected)
```python
# 1.1: Disease prevalence
disease_info = tu.tools.OpenTargets_get_disease_id_description_by_name(
diseaseName="non-small cell lung cancer"
)
# From literature: ~40% of NSCLC is PD-L1 TPS ≥50%
us_nsclc_annual = 200000
pdl1_high_rate = 0.40
pdl1_high_annual = us_nsclc_annual * pdl1_high_rate
print("PATIENT POPULATION SIZING: PD-L1 HIGH NSCLC")
print("="*80)
print(f"US NSCLC incidence: {us_nsclc_annual:,}/year")
print(f"PD-L1 TPS ≥50%: {pdl1_high_rate*100:.0f}% = {pdl1_high_annual:,}/year")
# 1.2: Eligibility criteria (first-line, no EGFR/ALK)
eligibility_factors = {
'no_egfr_alk': 0.80, # Exclude oncogene-driven
'age_18_plus': 0.98,
'ecog_0_1': 0.75,
'adequate_organ': 0.90,
'no_autoimmune': 0.85,
'no_prior_io': 1.00 # First-line
}
eligible_pool = pdl1_high_annual
print(f"\nEligibility Funnel:")
for criterion, factor in eligibility_factors.items():
eligible_pool *= factor
print(f" After {criterion}: {eligible_pool:,.0f} ({factor*100:.0f}%)")
print(f"\nFinal eligible pool: {eligible_pool:,.0f} patients/year (US)")
# 1.3: Enrollment projection for randomized trial
target_n = 120 # 60 per arm
sites = 30 # Large Phase 2b
capture_rate = 0.05 # 5% of eligible
monthly_enrollment = (eligible_pool * capture_rate) / 12 / sites
print(f"\nEnrollment Projection (Randomized 1:1):")
print(f" Target N: {target_n} ({target_n//2} per arm)")
print(f" Sites: {sites}")
print(f" Patients per site per month: {monthly_enrollment:.2f}")
print(f" Enrollment timeline: {target_n / (monthly_enrollment * sites):.1f} months")
```
### Step 2: Comparator Analysis (Pembrolizumab SOC)
```python
# 2.1: Get pembrolizumab info
pembro_info = tu.tools.drugbank_get_drug_basic_info_by_drug_name_or_id(
drug_name_or_drugbank_id=comparator
)
pembro_indications = tu.tools.drugbank_get_indications_by_drug_name_or_drugbank_id(
drug_name_or_drugbank_id=comparator
)
print("\nCOMPARATOR DRUG: PEMBROLIZUMAB")
print("="*80)
print(f"Status: {pembro_info['data']['groups']}")
print(f"Indications: {len(pembro_indications['data'])}")
# 2.2: Get FDA approval history
pembro_approval = tu.tools.OpenFDA_get_approval_history(
drug_name=comparator
)
# 2.3: Get pivotal trial data
keynote_trials = tu.tools.search_clinical_trials(
intervention="pembrolizumab",
condition="non-small cell lung cancer",
phase="3",
status="completed"
)
print(f"\nPembrolizumab Phase 3 trials in NSCLC: {len(keynote_trials['data'])}")
# Key trial: KEYNOTE-024 (1L, PD-L1 ≥50%)
print("\n" + "="*80)
print("KEYNOTE-024: Pembrolizumab vs. Chemotherapy (PD-L1 ≥50%)")
print("="*80)
print("Design: Randomized 1:1, N=305")
print("Population: 1L NSCLC, PD-L1 TPS ≥50%")
print("Primary: PFS")
print("\nResults:")
print(" Pembrolizumab:")
print(" - ORR: 44.8%")
print(" - Median PFS: 10.3 months")
print(" - Median OS: 30.0 months (30-month landmark)")
print(" Chemotherapy:")
print(" - ORR: 27.8%")
print(" - Median PFS: 6.0 months")
print(" - Median OS: 14.2 months")
print("\nConclusion: Pembrolizumab is SOC for PD-L1 ≥50% NSCLC")
# 2.4: Comparator drug sourcing
print("\n" + "="*80)
print("COMPARATOR SOURCING")
print("="*80)
print("Drug: Pembrolizumab (Keytruda)")
print("Availability: Commercial supply")
print("Cost: ~$150-180K/year per patient")
print("Dosing: 200 mg IV q3w")
print("Stability: Refrigerated, 24-hour room temp after reconstitution")
print("Sourcing: Purchase from Merck or specialty pharmacy")
print("IRB Consideration: Standard of care, no IND required for comparator arm")
```
### Step 3: Sample Size Calculation (Superiority Design)
```python
print("\n" + "="*80)
print("SAMPLE SIZE CALCULATION: SUPERIORITY TRIAL (ORR)")
print("="*80)
# Assumptions
pembro_orr = 0.45 # 45% from KEYNOTE-024
target_orr = 0.60 # 60% for novel drug (15% absolute improvement)
alpha = 0.05 # Two-sided
power = 0.80
dropout = 0.10
# Calculate (using normal approximation for proportions)
import math
def sample_size_two_proportions(p1, p2, alpha=0.05, power=0.80):
"""Calculate sample size for comparing two proportions"""
z_alpha = 1.96 # Two-sided alpha=0.05
z_beta = 0.84 # Power=0.80
p_avg = (p1 + p2) / 2
n = ((z_alpha * math.sqrt(2 * p_avg * (1 - p_avg)) +
z_beta * math.sqrt(p1 * (1 - p1) + p2 * (1 - p2)))**2 /
(p1 - p2)**2)
return math.ceil(n)
n_per_arm = sample_size_two_proportions(target_orr, pembro_orr)
n_total = n_per_arm * 2
n_with_dropout = math.ceil(n_total / (1 - dropout))
print(f"Null Hypothesis (H0): ORR_novel = ORR_pembro = {pembro_orr*100:.0f}%")
print(f"Alternative (H1): ORR_novel = {target_orr*100:.0f}% (15% absolute improvement)")
print(f"Alpha: {alpha} (two-sided)")
print(f"Power: {power*100:.0f}%")
print(f"\nSample Size:")
print(f" Per arm: {n_per_arm}")
print(f" Total: {n_total}")
print(f" With {dropout*100:.0f}% dropout: {n_with_dropout} ({n_with_dropout//2}/arm)")
print(f"\n⚠ NOTE: This is Phase 2b, not pivotal")
print(f" - Powering for hypothesis generation, not definitive proof")
print(f" - N={n_with_dropout} reasonable for Phase 2b go/no-go decision")
print(f" - Successful Phase 2b → Phase 3 with PFS/OS primary (N=400-600)")
# 2.5: Alternative: Non-inferiority design (if aiming for better safety)
print("\n" + "="*80)
print("ALTERNATIVE DESIGN: NON-INFERIORITY (If Better Safety)")
print("="*80)
print("Rationale: If novel drug has lower toxicity (e.g., no pneumonitis)")
print("Non-inferiority margin: Δ = -10% (ORR novel ≥ 35% if pembro 45%)")
print("Sample size: ~200/arm (larger N for non-inferiority)")
print("Conclusion: STICK WITH SUPERIORITY for Phase 2b (smaller N)")
```
### Step 4: Safety Comparison
```python
# 4.1: Pembrolizumab safety profile
pembro_warnings = tu.tools.FDA_get_warnings_and_cautions_by_drug_name(
drug_name=comparator
)
pembro_faers = tu.tools.FAERS_count_reactions_by_drug_event(
medicinalproduct="PEMBROLIZUMAB"
)
print("\n" + "="*80)
print("SAFETY PROFILE: PEMBROLIZUMAB (COMPARATOR)")
print("="*80)
print(f"FDA warnings: {len(pembro_warnings.get('data', []))}")
print("\nTop 10 Adverse Events (FAERS):")
for i, ae in enumerate(pembro_faers.get('results', [])[:10], 1):
print(f" {i}. {ae['term']}: {ae['count']} reports")
print("\nKey Immune-Related AEs (irAEs) from Label:")
irAEs = [
{'event': 'Pneumonitis', 'incidence': '3.4%', 'grade_3_4': '0.8%', 'fatal': '0.1%'},
{'event': 'Colitis', 'incidence': '1.7%', 'grade_3_4': '0.4%', 'fatal': '0%'},
{'event': 'Hepatitis', 'incidence': '0.7%', 'grade_3_4': '0.2%', 'fatal': '0.1%'},
{'event': 'Endocrinopathies (all)', 'incidence': '8.0%', 'grade_3_4': '0.8%', 'fatal': '0%'},
{'event': 'Nephritis', 'incidence': '0.7%', 'grade_3_4': '0.2%', 'fatal': '0%'}
]
print("\n" + "="*80)
print("IMMUNE-RELATED ADVERSE EVENTS (irAEs)")
print("="*80)
print(f"{'Event':<25} {'Any Grade':<12} {'Grade 3-4':<12} {'Fatal':<10}")
print("-" * 60)
for ae in irAEs:
print(f"{ae['event']:<25} {ae['incidence']:<12} {ae['grade_3_4']:<12} {ae['fatal']:<10}")
print("\n" + "="*80)
print("SAFETY MONITORING PLAN (Both Arms)")
print("="*80)
print("Standard immune-related AE monitoring:")
print(" - Baseline: CXR, PFTs (if smoker), TSH, LFTs, Cr")
print(" - Every cycle: CBC, CMP, LFTs, TSH")
print(" - PRN: CT chest for respiratory symptoms, cortisol/ACTH for fatigue")
print("\nStopping rules for irAEs:")
print(" - Grade 2 pneumonitis: Hold drug, imaging, pulmonology")
print(" - Grade 3-4 irAE: Discontinue drug, high-dose steroids (1-2 mg/kg)")
print(" - Grade 4 or fatal irAE: Report to FDA ASAP (IND safety report)")
```
### Final Feasibility & Design Recommendation
```python
print("\n" + "="*80)
print("FEASIBILITY SCORECARD: PEMBROLIZUMAB SUPERIORITY TRIAL")
print("="*80)
dimensions = {
'Patient Availability': {
'weight': 0.30,
'raw_score': 9,
'evidence': '★★★',
'rationale': '~40,000 eligible/year, rapid enrollment (6-8 months for N=120)'
},
'Endpoint Precedent': {
'weight': 0.25,
'raw_score': 9,
'evidence': '★★★',
'rationale': 'ORR standard for Phase 2, precedent in KEYNOTE trials'
},
'Regulatory Clarity': {
'weight': 0.20,
'raw_score': 8,
'evidence': '★★☆',
'rationale': 'Active control acceptable, Phase 3 will need PFS/OS'
},
'Comparator Feasibility': {
'weight': 0.15,
'raw_score': 9,
'evidence': '★★★',
'rationale': 'Pembrolizumab commercial supply, known efficacy (ORR 45%)'
},
'Safety Monitoring': {
'weight': 0.10,
'raw_score': 8,
'evidence': '★★★',
'rationale': 'PD-1 class effects well-known, irAE protocols established'
}
}
feasibility_score = sum(d['weight'] * d['raw_score'] * 10 for d in dimensions.values())
print(f"{'Dimension':<30} {'Weight':<10} {'Score':<10} {'Weighted':<10}")
print("-" * 70)
for dimension, data in dimensions.items():
weighted = data['weight'] * data['raw_score'] * 10
print(f"{dimension:<30} {data['weight']*100:.0f}%{'':<7} {data['raw_score']}/10{'':<5} {weighted:.1f}")
print("-" * 70)
print(f"TOTAL FEASIBILITY SCORE: {feasibility_score:.0f}/100 - HIGH")
print("\n" + "="*80)
print("FINAL RECOMMENDATION: RECOMMEND PROCEED")
print("="*80)
print(f"""
This Phase 2b randomized trial demonstrates HIGH feasibility (Score: {feasibility_score:.0f}/100).
RECOMMENDED DESIGN:
- Phase 2b, randomized 1:1, open-label
- N=120 (60 per arm) with 10% dropout buffer → Total N=132
- Population: 1L NSCLC, PD-L1 TPS ≥50%, no EGFR/ALK
- Treatment:
* Arm A: Novel PD-1 inhibitor [dose] IV q3w
* Arm B: Pembrolizumab 200 mg IV q3w
- Primary endpoint: ORR (RECIST 1.1, iRECIST for pseudoprogression)
- Secondary: PFS, OS (long-term FU), DoR, safety
- Duration: Until progression, toxicity, or 24 months
STATISTICAL PLAN:
- Power: 80% to detect 15% absolute ORR improvement (60% vs 45%)
- Analysis: Chi-square test, two-sided alpha=0.05
- Interim: 50% information (n=60), futility only (no early efficacy stop)
SUCCESS CRITERIA (Advance to Phase 3):
- ORR ≥ 55% (vs. pembro 45%, p<0.05)
- Safety profile non-inferior (no new safety signals)
- PFS trend favorable (HR <0.85)
- Duration of response ≥12 months (median)
ENROLLMENT:
- Timeline: 6-8 months (30 sites, ~0.5 patients/site/month)
- Primary analysis: Month 14 (6-month follow-up for ORR assessment)
BUDGET: $6-9M (higher cost due to comparator drug purchase + 2× monitoring)
""")
```
---
## Example 4: Non-Inferiority Trial (Oral Anticoagulant)
**Scenario**: Design Phase 3 non-inferiority trial for novel oral Factor XIa inhibitor vs. apixaban in atrial fibrillation, aiming for lower bleeding risk.
```python
from tooluniverse import ToolUniverse
tu = ToolUniverse(use_cache=True)
tu.load_tools()
indication = "Atrial fibrillation, stroke prevention"
design = "Phase 3, randomized, double-blind, non-inferiority"
primary_endpoint = "Stroke or systemic embolism (composite)"
comparator = "apixaban"
# Step 1: Patient Population (Very Large)
print("PATIENT POPULATION: ATRIAL FIBRILLATION")
print("="*80)
# AFib prevalence: ~6M in US, ~33% on oral anticoagulation
us_afib_prevalence = 6000000
on_anticoagulation = us_afib_prevalence * 0.33
print(f"US AFib prevalence: {us_afib_prevalence:,}")
print(f"On oral anticoagulation: {on_anticoagulation:,}")
print(f"Eligible for trial: ~50% = {on_anticoagulation * 0.5:,.0f}")
# Step 2: Comparator (Apixaban - Standard of Care)
apixaban_info = tu.tools.drugbank_get_drug_basic_info_by_drug_name_or_id(
drug_name_or_drugbank_id=comparator
)
print(f"\nComparator: {comparator}")
print(f"Status: {apixaban_info['data']['groups']}")
# From ARISTOTLE trial: Apixaban vs. warfarin
print("\nARISTOTLE Trial (Apixaban Pivotal):")
print(" N=18,201")
print(" Stroke/SE rate: 1.27%/year (apixaban) vs. 1.60%/year (warfarin)")
print(" Major bleeding: 2.13%/year (apixaban) vs. 3.09%/year (warfarin)")
# Step 3: Non-Inferiority Margin
print("\n" + "="*80)
print("NON-INFERIORITY MARGIN DETERMINATION")
print("="*80)
print("Regulatory Guidance (FDA/EMA):")
print(" - NI margin = Fraction of comparator effect vs. placebo")
print(" - Apixaban vs. warfarin: 21% relative risk reduction in stroke")
print(" - Acceptable to preserve ≥50% of effect → NI margin = HR <1.38")
print("\nProposed NI Margin: HR <1.44 (upper bound of 95% CI)")
print("Rationale: Conservative, if novel drug has 50% lower bleeding")
# Step 4: Sample Size (LARGE)
print("\n" + "="*80)
print("SAMPLE SIZE CALCULATION: NON-INFERIORITY (TIME-TO-EVENT)")
print("="*80)
# Assumptions
stroke_rate_annual = 0.0127 # 1.27%/year from ARISTOTLE
ni_margin_hr = 1.44
alpha = 0.025 # One-sided for NI
power = 0.90
enrollment_period = 24 # months
follow_up = 36 # months
# Events needed (conservative estimate)
events_needed = 450 # Assuming HR=1.0, NI margin 1.44, 90% power
# Sample size (based on event rate)
n_per_arm = events_needed / (2 * stroke_rate_annual * (enrollment_period + follow_up) / 12)
n_total = n_per_arm * 2
print(f"Assumptions:")
print(f" Annual event rate: {stroke_rate_annual*100:.2f}%")
print(f" NI margin: HR <{ni_margin_hr}")
print(f" Power: {power*100:.0f}%")
print(f" Alpha: {alpha} (one-sided)")
print(f"\nRequired events: {events_needed}")
print(f"Sample size: {n_total:,.0f} ({n_per_arm:,.0f} per arm)")
print(f"Duration: {enrollment_period} months enrollment + {follow_up} months follow-up = {enrollment_period + follow_up} months")
print(f"\n⚠ CHALLENGE: VERY LARGE TRIAL (N={n_total:,.0f})")
print(f" - Phase 3 only (skip Phase 2 or run small Phase 2 for dose)")
print(f" - Multi-national (US, EU, Asia, LatAm)")
print(f" - Budget: $150-250M")
# Step 5: Regulatory Considerations
print("\n" + "="*80)
print("REGULATORY PATHWAY: CARDIOVASCULAR OUTCOMES TRIAL")
print("="*80)
print("FDA Requirements:")
print(" - Pre-IND: Type C meeting for NI margin discussion")
print(" - Phase 3 design: Randomized, double-blind, event-driven")
print(" - Primary: Stroke/SE (non-inferiority)")
print(" - Key secondary: Major bleeding (superiority)")
print(" - DSMB: Independent, frequent reviews (every 200 events)")
print(" - Interim: 1-2 analyses (efficacy + futility)")
print("\nApproval Pathway: Regular NDA (not accelerated)")
# Feasibility Score
print("\n" + "="*80)
print("FEASIBILITY SCORE: NON-INFERIORITY TRIAL")
print("="*80)
dimensions = {
'Patient Availability': {'weight': 0.30, 'raw_score': 10, 'rationale': 'Huge population (>1M eligible)'},
'Endpoint Precedent': {'weight': 0.25, 'raw_score': 10, 'rationale': 'Stroke/SE standard, regulatory accepted'},
'Regulatory Clarity': {'weight': 0.20, 'raw_score': 7, 'rationale': 'NI margin needs FDA agreement, precedent exists'},
'Comparator Feasibility': {'weight': 0.15, 'raw_score': 9, 'rationale': 'Apixaban generic, widely used'},
'Safety Monitoring': {'weight': 0.10, 'raw_score': 9, 'rationale': 'Bleeding monitoring standard, established'}
}
feasibility_score = sum(d['weight'] * d['raw_score'] * 10 for d in dimensions.values())
print(f"TOTAL FEASIBILITY SCORE: {feasibility_score:.0f}/100 - HIGH (but expensive)")
print(f"\nRECOMMENDATION: CONDITIONAL GO (if funded)")
print(f" - Feasibility: HIGH for patient access, endpoints, regulatory")
print(f" - Challenge: $150-250M budget, 5-year duration")
print(f" - Strategy: Partner with large pharma or seek CV outcomes specialist CRO")
```
---
## Example 5: Basket Trial (Multiple Cancers, One Biomarker)
**Scenario**: Design basket trial for NTRK fusion-positive solid tumors (tissue-agnostic), following larotrectinib precedent.
```python
from tooluniverse import ToolUniverse
tu = ToolUniverse(use_cache=True)
tu.load_tools()
indication = "NTRK fusion-positive solid tumors (basket trial)"
design = "Phase 2, single-arm, basket (multiple histologies)"
primary_endpoint = "Objective Response Rate (ORR) by histology"
biomarker = "NTRK1/2/3 gene fusion"
# Step 1: Biomarker Prevalence (Rare but Pan-Cancer)
print("BIOMARKER PREVALENCE: NTRK FUSIONS")
print("="*80)
# NTRK fusions: rare (<1% most cancers, enriched in pediatric/rare tumors)
ntrk_prevalence_by_cancer = [
{'cancer': 'Secretory breast carcinoma', 'prevalence': 0.90, 'annual_us': 100},
{'cancer': 'Mammary analogue secretory carcinoma', 'prevalence': 0.95, 'annual_us': 50},
{'cancer': 'Infantile fibrosarcoma', 'prevalence': 0.90, 'annual_us': 30},
{'cancer': 'NSCLC', 'prevalence': 0.01, 'annual_us': 2000}, # 1% of 200K
{'cancer': 'Colorectal cancer', 'prevalence': 0.005, 'annual_us': 700}, # 0.5% of 140K
{'cancer': 'Thyroid cancer', 'prevalence': 0.05, 'annual_us': 250},
{'cancer': 'Glioblastoma', 'prevalence': 0.01, 'annual_us': 130},
{'cancer': 'Salivary gland', 'prevalence': 0.03, 'annual_us': 10},
{'cancer': 'Sarcoma (other)', 'prevalence': 0.02, 'annual_us': 250},
{'cancer': 'Melanoma', 'prevalence': 0.001, 'annual_us': 90}
]
print(f"{'Cancer Type':<40} {'NTRK+ Rate':<15} {'Annual US Cases':<20}")
print("-" * 80)
total_ntrk_patients = 0
for cancer in ntrk_prevalence_by_cancer:
print(f"{cancer['cancer']:<40} {cancer['prevalence']*100:>6.1f}% {cancer['annual_us']:>15,}")
total_ntrk_patients += cancer['annual_us']
print("-" * 80)
print(f"{'TOTAL NTRK+ PATIENTS/YEAR (US)':<40} {'':<15} {total_ntrk_patients:>15,}")
print(f"\nKey Insight: NTRK fusions are RARE (~{total_ntrk_patients:,}/year across all cancers)")
print(f" → Basket trial required to aggregate sufficient patients")
# Step 2: Basket Trial Design
print("\n" + "="*80)
print("BASKET TRIAL DESIGN")
print("="*80)
print("Concept: Enroll patients across MULTIPLE tumor types with NTRK fusions")
print("Rationale: NTRK inhibitor mechanism is tumor-agnostic")
print("\nDesign:")
print(" - Single-arm, open-label")
print(" - Primary endpoint: ORR per histology (≥15 patients/basket)")
print(" - Secondary: DoR, PFS, OS, safety (across all baskets)")
print(" - Enrollment: ~80-120 patients across 8-12 tumor types")
print("\nInclusion Criteria:")
print(" - NTRK1/2/3 fusion confirmed (NGS, FISH, IHC→FISH)")
print(" - Locally advanced or metastatic disease")
print(" - Measurable disease (RECIST 1.1)")
print(" - No effective standard therapy OR progressed on SOC")
print(" - Age ≥12 years (include pediatric)")
# Step 3: Biomarker Testing Strategy
print("\n" + "="*80)
print("BIOMARKER TESTING STRATEGY")
print("="*80)
# Search for NGS panels
print("NGS-based comprehensive genomic profiling (CGP):")
print(" - FoundationOne CDx (FDA-approved CDx for larotrectinib)")
print(" - Guardant360 (liquid biopsy, ctDNA)")
print(" - Institutional NGS (CLIA-certified)")
print("\nTesting Algorithm:")
print(" 1. IHC screening (pan-TRK antibody) - Fast, cheap")
print(" → If positive: Confirm with NGS or FISH")
print(" 2. NGS (if tumor profiling already done)")
print(" 3. FISH (if NGS unavailable or IHC+)")
print("\nTurnaround: 10-14 days (NGS), 5-7 days (FISH)")
print("Cost: $500-800 (IHC), $3,000-5,000 (NGS)")
# Search for testing guidelines
testing_papers = tu.tools.PubMed_search_articles(
query="NTRK fusion testing guidelines NCCN NGS",
max_results=20
)
print(f"\nNTRK testing guideline papers: {len(testing_papers['data'])}")
# Step 4: Regulatory Precedent (Larotrectinib)
print("\n" + "="*80)
print("REGULATORY PRECEDENT: LAROTRECTINIB (Vitrakvi)")
print("="*80)
# Search for larotrectinib approval
laro_papers = tu.tools.PubMed_search_articles(
query="larotrectinib FDA approval NTRK fusion basket trial",
max_results=25
)
print(f"Larotrectinib papers: {len(laro_papers['data'])}")
print("\nLarotrectinib FDA Approval (2018):")
print(" Indication: NTRK fusion-positive solid tumors (TISSUE-AGNOSTIC)")
print(" Trial Design: Basket trial, single-arm, n=55")
print(" Primary Endpoint: ORR")
print(" Results:")
print(" - Overall ORR: 75% (95% CI: 61-85%)")
print(" - Complete response: 13%")
print(" - Partial response: 62%")
print(" - Median DoR: NOT REACHED (73% at 12 months)")
print(" Histologies enrolled: 17 different tumor types")
print(" Approval: ACCELERATED (tissue-agnostic, first of its kind)")
print("\nKey Regulatory Insights:")
print(" ✓ Single-arm acceptable (no SOC for NTRK+ tumors)")
print(" ✓ ORR primary endpoint sufficient")
print(" ✓ Small N (n=55) acceptable given tumor rarity")
print(" ✓ Tissue-agnostic approval precedent SET")
# Step 5: Enrollment Feasibility
print("\n" + "="*80)
print("ENROLLMENT STRATEGY")
print("="*80)
print(f"Total NTRK+ patients/year (US): ~{total_ntrk_patients:,}")
print(f"Target enrollment: 100 patients")
print(f"Capture rate needed: {100/total_ntrk_patients*100:.1f}%")
print("\nChallenges:")
print(" 1. BROAD SCREENING: Need to test 10,000+ patients to find 100 NTRK+")
print(" 2. Competing trials: Larotrectinib, entrectinib already approved")
print(" 3. Limited testing: Not all centers do NGS routinely")
print("\nMitigation Strategies:")
print(" 1. PARTNER WITH CGP COMPANIES:")
print(" - Foundation Medicine, Guardant, Tempus")
print(" - Flag NTRK+ patients in CGP reports → refer to trial")
print(" 2. NATIONAL SCREENING PROGRAM:")
print(" - Provide free NGS testing for suspected rare fusions")
print(" 3. PATIENT ADVOCACY:")
print(" - Partner with LUNGevity, CRC Alliance, sarcoma foundations")
print(" 4. PEDIATRIC SITES:")
print(" - Children's hospitals (infantile fibrosarcoma enriched)")
print(" 5. INTERNATIONAL EXPANSION:")
print(" - EU, Asia sites (3× enrollment pool)")
print("\nProjected Enrollment Timeline:")
print(" - US sites: 25-30 (comprehensive cancer centers)")
print(" - International: 20-30")
print(" - Monthly enrollment: 2-3 patients (across all sites)")
print(" - Duration: 36-48 months to reach n=100")
# Step 6: Statistical Design
print("\n" + "="*80)
print("STATISTICAL DESIGN (BASKET TRIAL)")
print("="*80)
print("Primary Analysis: ORR per tumor type")
print(" - Minimum 15 patients per basket for analysis")
print(" - Success threshold: ORR ≥40% (vs. null ≤10%)")
print(" - If 6/15 respond (40%), 95% CI: 16-68% → Clinically meaningful")
print("\nOverall Analysis (All Tumor Types Combined):")
print(" - Secondary analysis")
print(" - Target overall ORR: ≥60% (following larotrectinib)")
print("\nInterim Analysis:")
print(" - After 30 patients: Assess safety, futility")
print(" - If ORR <20%, consider stopping")
# Feasibility Score
print("\n" + "="*80)
print("FEASIBILITY SCORECARD: NTRK BASKET TRIAL")
print("="*80)
dimensions = {
'Patient Availability': {
'weight': 0.30,
'raw_score': 4,
'evidence': '★★★',
'rationale': 'VERY RARE (~3.6K/year US), need broad screening'
},
'Endpoint Precedent': {
'weight': 0.25,
'raw_score': 10,
'evidence': '★★★',
'rationale': 'ORR accepted, larotrectinib precedent (tissue-agnostic approval)'
},
'Regulatory Clarity': {
'weight': 0.20,
'raw_score': 9,
'evidence': '★★★',
'rationale': 'Clear path (larotrectinib precedent), accelerated approval'
},
'Comparator Feasibility': {
'weight': 0.15,
'raw_score': 8,
'evidence': '★★☆',
'rationale': 'Single-arm acceptable (no SOC for NTRK+), larotrectinib approved'
},
'Safety Monitoring': {
'weight': 0.10,
'raw_score': 8,
'evidence': '★★☆',
'rationale': 'TRK inhibitor class known, manageable AEs'
}
}
feasibility_score = sum(d['weight'] * d['raw_score'] * 10 for d in dimensions.values())
print(f"{'Dimension':<30} {'Weight':<10} {'Score':<10} {'Weighted':<10}")
print("-" * 70)
for dimension, data in dimensions.items():
weighted = data['weight'] * data['raw_score'] * 10
print(f"{dimension:<30} {data['weight']*100:.0f}%{'':<7} {data['raw_score']}/10{'':<5} {weighted:.1f}")
print("-" * 70)
print(f"TOTAL FEASIBILITY SCORE: {feasibility_score:.0f}/100 - MODERATE")
print("\n" + "="*80)
print("FINAL RECOMMENDATION: CONDITIONAL GO")
print("="*80)
print("""
This basket trial demonstrates MODERATE feasibility (Score: 68/100).
CRITICAL SUCCESS FACTOR: Screening Partnership
- NTRK fusions are ultra-rare (<0.5% across cancers)
- MUST partner with CGP companies (Foundation, Guardant) to identify patients
- Alternative: Provide sponsored NGS testing program
STRENGTHS:
- Clear regulatory path (larotrectinib precedent)
- ORR endpoint accepted for tissue-agnostic approval
- High unmet need (no effective SOC for NTRK+ tumors)
CHALLENGES:
- Slow enrollment (36-48 months for n=100)
- Competing drugs (larotrectinib, entrectinib already approved)
- High screening costs (need to test 10,000+ patients)
RECOMMENDED STRATEGY:
1. Phase 1 dose escalation (n=20-30, multiple tumor types)
2. Phase 2 basket expansion (n=80-100, ≥15 per histology)
3. Concurrent: Pediatric arm (infantile fibrosarcoma, few alternatives)
4. Regulatory: Breakthrough therapy designation (after Phase 1 signals)
5. Screening: Partner with 2-3 CGP companies, patient registries
BUDGET: $15-25M (high screening costs, slow enrollment)
TIMELINE: 48-60 months (enrollment) + 12-18 months (follow-up for DoR)
""")
```
---
## Summary Table: All 5 Examples
| Example | Phase | Design | Indication | Biomarker | Primary Endpoint | Feasibility Score | Recommendation | Key Challenge |
|---------|-------|--------|------------|-----------|------------------|-------------------|----------------|---------------|
| 1. EGFR+ NSCLC | 1/2 | Single-arm | Osimertinib-resistant NSCLC | EGFR L858R | ORR | 82/100 (HIGH) | PROCEED | None major |
| 2. Niemann-Pick C | 2 | Single-arm vs. NH | Rare lysosomal storage | Genetic (NPC1/2) | Clinical severity score | 58/100 (MOD-LOW) | CONDITIONAL GO | Slow enrollment (36+ mo) |
| 3. PD-L1 High NSCLC | 2b | Randomized 1:1 | First-line NSCLC | PD-L1 TPS ≥50% | ORR | 87/100 (HIGH) | PROCEED | Comparator cost |
| 4. Atrial Fibrillation | 3 | Non-inferiority | AFib stroke prevention | None | Stroke/SE | 90/100 (HIGH) | CONDITIONAL GO | Large N, expensive ($150-250M) |
| 5. NTRK Basket | 2 | Basket, single-arm | Pan-cancer | NTRK fusion | ORR by histology | 68/100 (MODERATE) | CONDITIONAL GO | Ultra-rare (broad screening) |
**Key Learnings**:
- Biomarker-selected oncology trials (Ex 1, 3) have HIGH feasibility
- Rare diseases (Ex 2) face enrollment challenges → need registries
- Non-inferiority trials (Ex 4) are feasible but expensive (large N)
- Basket trials (Ex 5) require broad screening partnerships