Concrete examples of trial feasibility assessments using ToolUniverse.
Scenario: Assess feasibility of Phase 1/2 trial for novel EGFR inhibitor in EGFR L858R+ NSCLC patients who progressed on osimertinib.
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"# 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_gene_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
# 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}")# 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.FDA_get_drug_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")# 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)")# 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")# 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")# 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)
""")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.
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"# 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)
# 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")# 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")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)
""")Scenario: Design Phase 2b randomized trial for novel PD-1 inhibitor vs. pembrolizumab in PD-L1 high (TPS ≥50%) NSCLC, first-line.
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"# 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")# 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.FDA_get_drug_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")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)")# 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)")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)
""")Scenario: Design Phase 3 non-inferiority trial for novel oral Factor XIa inhibitor vs. apixaban in atrial fibrillation, aiming for lower bleeding risk.
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")Scenario: Design basket trial for NTRK fusion-positive solid tumors (tissue-agnostic), following larotrectinib precedent.
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)
""")| 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