TLS Model Report

One expression-only TLS model for Visium spots and bulk RNA-seq · validation on held-out, out-of-distribution and immunotherapy cohorts · aggregates only

Summary

One expression-only model reads tertiary lymphoid structures (TLS) from a Visium spot or from a bulk RNA-seq sample, one sample at a time. It was trained on spot annotations from spatial transcriptomics together with pathologist TLS calls on bulk tumours, selected by grouped cross-validation, and checked once on two locked out-of-distribution (OOD) cohorts. It was then frozen and scored in 2,689 patients treated with immune checkpoint inhibitors (ICI).

  • Spots work. Held-out Visium patients: AUROC 0.930 [0.886, 0.960].
  • Bulk ranks TLS across cancer types, weakly within one. Held-out bulk, pooled: AUROC 0.757 [0.679, 0.827]; within a cohort 0.45–0.70 with wide intervals. Every model family, published signatures included, stays near 0.55–0.65 here.
  • OOD, scored once. Internal lung 0.855 [0.742, 0.950], CPTAC-PAAD 0.641 [0.543, 0.738].
  • Immunotherapy. A higher score goes with longer survival and more responses, but the effect is small (pooled OS HR 0.92 per SD), and the model is not better than the 12-chemokine signature: added on top of it, it contributes nothing (likelihood-ratio tests near null). A positive interaction of the two scores appears in bladder cancer (IMvigor210) and ccRCC; it is uncorrected for multiplicity and is a hypothesis.

Background

A TLS is an ectopic lymphoid organ that forms inside chronically inflamed tissue, tumours included: a B-cell follicle (mature TLS carry a germinal centre and follicular dendritic cells), a T-cell zone and high endothelial venules. In 540 tumours treated with anti-PD-1 / PD-L1, mature TLS predicted objective response (43.1% vs 19.6%), PFS and OS independently of PD-L1 and CD8 density (Vanhersecke et al., Nat Cancer 2021, doi:10.1038/s43018-021-00232-6).

TLS are scored on H&E, multiplex immunofluorescence or spatial transcriptomics: accurate, but slow and costly. Bulk RNA-seq is routine, yet bulk TLS signatures are imprecise against pathologist calls. This project trains one model on both worlds so that the same model scores a spot or a bulk sample.

TLS formation and maturation, what they release, and the transcriptomic markers of each stage.
00_tls_biology.png · TLS formation and maturation, what they release, and the transcriptomic markers of each stage.
TLS cell types and signalling markers (chemokines, receptors, LTBR ligands) and the two ways TLS kill tumour cells: antibodies and cytotoxic T cells.
00_tls_mechanisms.png · TLS cell types and signalling markers (chemokines, receptors, LTBR ligands) and the two ways TLS kill tumour cells: antibodies and cytotoxic T cells.
TLS across solid cancers: presence, induction, prognosis, detection method, surrogate response markers and TLS-guided clinical trials.
00_tls_in_solid_cancers.png · TLS across solid cancers: presence, induction, prognosis, detection method, surrogate response markers and TLS-guided clinical trials.

Data

Bulk cohorts and their roles. TLS+ counts are pathologist calls except TCGA-BRCA and part of TCGA-LUAD, where HookNet-TLS labels (CNN) were used for training only; every test and OOD metric uses pathologist labels.

cohortntls_posmaturity_knownmaturepathologistcnnrole
CPTAC-PAAD12954.0005411.0001290OOD (locked)
CPTAC-ccRCC8625.00000.000860train/test
Internal_lung4717.00000.000470OOD (locked)
MGH_LUAD_DagogoJack129.00091.000120train/test
TCGA-BRCA420203899.000153267train/test
TCGA-KIRC/KIRP/KICH21023.00000.0002100train/test
TCGA-LUAD45134515821.000221230train/test
TCGA-PAAD11889.0008917.0001180train/test

Visium: GSE175540 (ccRCC, 23 sections, FFPE and frozen; Meylan Immunity 2022) and USZ (8 FFPE kidney and lung sections; Zenodo 14620362, CC-BY-4.0). Splits are by patient: about 25% of Visium patients and 20% of bulk patients per cohort are held out. Non-public cohorts (Internal lung, MGH) stay outside the repository.

Label ceiling, TCGA-LUAD: two pathologists agree almost perfectly with each other (κ 0.96), while two runs of the public HookNet-TLS model (HookNet-TLS_a, HookNet-TLS_b) agree with pathologists only moderately (κ 0.20–0.51) and with each other poorly (κ 0.20). A model trained partly on these CNN labels cannot be expected to beat that agreement.

source_asource_bnagreementkappa
HookNet-TLS_a#3HookNet-TLS_b#44310.8450.198
HookNet-TLS_a#3pathologist_HE#11650.7700.388
HookNet-TLS_a#3pathologist_HE#21970.8170.514
HookNet-TLS_b#4pathologist_HE#11590.7550.195
HookNet-TLS_b#4pathologist_HE#21880.7710.244
pathologist_HE#1pathologist_HE#21390.9860.964

Methods

Model

  • Units. A bulk sample, a Visium spot, an aggregate of k neighbouring spots (k = 1, 7, 19) and a whole-section pseudo-bulk; all share one gene panel (16,788 genes detected on every platform).
  • Features. Within-sample ranks (chosen in stage A over log2(TPM+1); the bulk↔Visium platform offset did not help and was dropped), ssGSEA of 30 public signatures, their pairwise products and products of the top signature genes chosen inside each fold.
  • Ladder. Signature baseline, elastic-net logistic regression, k-top-scoring pairs, LightGBM; feature selection by correlation or by mean |SHAP|, both inside folds.
  • Selection. Grouped 5-fold CV over training patients; the score weighs mean within-cohort bulk AUROC (pooled AUROC rewards telling cancer types apart) and spot AUROC. Winner: LightGBM with SHAP selection.
  • Calibration. Platt scaling on out-of-fold predictions, separately for bulk and spot units; spot probabilities corrected for the TLS-enriched sampling of training spots.
  • Evaluation. Held-out patients; bootstrap 95% CI for every metric; OOD cohorts scored once, with nothing tuned afterwards; leave-one-cohort-out reported for robustness only.

Signature scores (baselines)

  • Gene sets. Cabrita TLS signature (Cabrita et al., Nature 2020; 9 genes: CD1D, CETP, LAT, SKAP1, CCR6, RBP5, CD79B, EIF1AY, PTGDS). 12-chemokine (Coppola et al., Am J Pathol 2011; CXCL9, CXCL10, CXCL11, CXCL13, CCL2, CCL3, CCL4, CCL5, CCL8, CCL18, CCL19, CCL21). TLS imprint (Meylan et al., Immunity 2022; 29 genes as listed in Nat Commun 2025, PMC12059173; PTLP is not an HGNC symbol and is absent, so 28 genes are scored).
  • Method. Single-sample GSEA (Barbie et al., Nature 2009), one sample at a time, no reference cohort. Genes of a sample are ranked by expression (average ranks for ties); with rank r and weight w = r0.25, the score is the weighted mean rank of the set's genes minus the mean rank of all other genes. This is the closed form of the ssGSEA running sum, unnormalised (no rescaling to the range of a cohort). Genes of a set missing from the matrix are skipped.
  • Input. log2(TPM+1). ICI cohorts: all 20,062 genes shared by the 28 studies. Bulk ROC: all 20,062 genes of the bulk matrix. Visium spots: only the model's gene panel (5,049 genes), so spot-level signature scores are an approximation.
  • Scale in outcome models. Each score, ours included (ours on the logit scale of P(TLS)), is z-scored within cohort before modelling, so effects read per 1 SD inside a study.
  • The same ssGSEA implementation computes the 30 signature features inside our model.

Immunotherapy validation

  • Cohorts. 28 published or internal ICI studies; regimens containing an ICI only (ICI with TKI, bevacizumab or chemotherapy kept; TKI / mTOR / EGFR-only arms dropped); duplicate samples removed.
  • Scores. Our P(TLS) on the logit scale, and three published TLS signatures as baselines: Cabrita (Nature 2020), 12-chemokine (Coppola, AJP 2011) and the TLS imprint (Meylan, Immunity 2022; 29 genes), all ssGSEA on log2(TPM+1). Every score is z-scored within cohort, so HR and OR are per 1 SD.
  • Endpoints. OS and PFS (Cox, stratified by cohort; lifelines); objective response from RECIST (CR/PR vs SD/PD; study-annotated R/NR only where RECIST is missing) and disease control (CR/PR/SD vs PD) by logistic regression with cohort fixed effects (statsmodels).
  • Confounders in every model: ICI class, age, sex, stage, site, location. A missing category is its own level; missing age is median-imputed with a missing indicator; covariates without variation inside cohorts are dropped.
  • Comparison. ΔC-index (OS, PFS) and ΔAUC (response, DCR) between models on the same patients, with a paired bootstrap: patients resampled within cohort, every model refitted, 20 replicates.
  • TMB and PD-L1. TMB-high = ≥ 10 mut/Mb (studies reporting raw mutation counts excluded); PD-L1 = tumour-cell IHC category TC0 / TC1 / TC2+ as an ordinal covariate. Pooled always; a diagnosis alone only with ≥ 30 OS events.
  • Added value over the 12-chemokine signature. Nested models with the same confounders on complete cases. a 12-chemokine + ours vs 12-chemokine; b 12-chemokine + ours + 12-chemokine × ours vs 12-chemokine, and vs a. On the TMB + PD-L1 subset (both as covariates, never in an interaction): c ours over TMB + PD-L1; d ours over TMB + PD-L1 + 12-chemokine; e with the 12-chemokine × ours term, vs the d base and vs d. The primary statistic is the likelihood-ratio test of each nested pair; Δ and HR / OR are descriptive.

Course of the work

  1. Plan. One model with a TLS head and a maturity head; OOD cohorts locked before any training.
  2. First run, three fixes. The elastic-net solver was slow and over-shrunk (replaced by SGD). The maturity head looked inverted on bulk because all mature positives fell into one or two folds (fixed by stratifying folds by data block and label). Bulk model selection moved to within-cohort AUROC.
  3. Stage A. Rank features beat log-expression; the platform offset did not help.
  4. Stage B. LightGBM with SHAP selection had the best selection score; signature baselines were close.
  5. Review. Calibration by unit type, lymph-node spots removed before aggregation, unknown labels made explicit; leave-one-cohort-out kept as a robustness table only.
  6. Maturity head removed. Bulk maturity showed no signal.
  7. OOD scored once and reported as is.
  8. Immunotherapy. Model frozen; 28 studies harmonised; baselines, Cox and logistic models, TMB + PD-L1 subset.
  9. Added value. Nested models with the 12-chemokine signature and its interaction with our score.

Model results

Cross-validation

Stage A · feature representation (elastic net, correlation selection)
representationoffsetbulk AUROC, within cohortspot AUROCbulk AUROC, pooledselection score
rankFalse0.6370.7840.7280.710
logFalse0.6060.7190.7270.662
rankTrue0.5880.7360.7390.662
logTrue0.6330.6640.6770.649
Stage B · model × selector; the highest selection score was kept
candidatebulk AUROC, within cohortspot AUROCbulk AUROC, pooledselection score
lgbm|shap0.6100.8530.7720.731
enet|corr0.6370.7840.7280.710
lgbm|corr0.5850.8340.7670.709
ktsp|corr0.6320.7850.7830.709
signature|-0.6270.7820.7790.705
ktsp|shap0.5680.7770.7670.672
prev_panel|-0.6010.5870.7120.594
enet|shap0.5240.5130.4550.518

Held-out test and OOD

P(any TLS): held-out patients and the two OOD cohorts
evaluationblocknTLS+AUROCAUPRCBrier
testbulk:CPTAC-ccRCC1750.700 [0.433, 0.933]0.444 [0.200, 0.900]0.210 [0.110, 0.332]
testbulk:MGH_LUAD_DagogoJack321.000 [1.000, 1.000]1.000 [1.000, 1.000]0.088 [0.070, 0.126]
testbulk:TCGA-BRCA31180.491 [0.242, 0.702]0.599 [0.415, 0.817]0.245 [0.195, 0.295]
testbulk:TCGA-KIRC/KIRP/KICH4250.584 [0.214, 0.976]0.385 [0.056, 0.859]0.114 [0.060, 0.173]
testbulk:TCGA-LUAD45320.466 [0.278, 0.669]0.693 [0.537, 0.879]0.220 [0.168, 0.276]
testbulk:TCGA-PAAD24180.454 [0.195, 0.719]0.796 [0.626, 0.943]0.209 [0.128, 0.293]
testbulk:all162800.757 [0.679, 0.827]0.705 [0.600, 0.808]0.192 [0.163, 0.225]
testvisium:spots252063740.930 [0.886, 0.960]0.306 [0.143, 0.492]0.013 [0.006, 0.022]
testvisium:sections761.000 [1.000, 1.000]1.000 [1.000, 1.000]0.339 [0.164, 0.449]
testvisium:section_spearman<NA><NA>–––
oodbulk:CPTAC-PAAD129540.641 [0.543, 0.738]0.610 [0.492, 0.726]0.248 [0.230, 0.266]
oodbulk:Internal_lung47170.855 [0.742, 0.950]0.797 [0.613, 0.929]0.211 [0.176, 0.248]
oodbulk:all176710.705 [0.630, 0.780]0.655 [0.547, 0.758]0.238 [0.221, 0.255]

Bulk maturity (pooled held-out): AUROC 0.441 [0.254, 0.635] — no usable signal, which is why the maturity output was removed.

Leave-one-cohort-out (robustness only; selection saw these cohorts)
left_outnn_posauroc
CPTAC-ccRCC86250.534
MGH_LUAD_DagogoJack1290.926
TCGA-BRCA153890.579
TCGA-KIRC/KIRP/KICH210230.615
TCGA-LUAD2211580.628
TCGA-PAAD118890.554

ROC by cohort (interactive)

Pathologist TLS labels on held-out patients and the two OOD cohorts; our final model against the three published signatures (ssGSEA on bulk; on spots the signatures use only the model's gene panel). Pick a cohort; hover a curve for its AUROC.

Our model leads on Visium spots, on the Internal lung OOD cohort and on bulk pooled across cohorts. Inside single held-out bulk cohorts (17–45 patients each) a published signature is often as good or better, e.g. the 12-chemokine signature in TCGA-PAAD and CPTAC-ccRCC; these cohorts are small and their intervals wide.

Visium spot labels on example sections.
01_label_maps.png · Visium spot labels on example sections.
Bulk cohorts, PCA of the shared gene panel: cohorts separate, so pooled AUROC is easy and within-cohort AUROC is the honest metric.
02_bulk_pca.png · Bulk cohorts, PCA of the shared gene panel: cohorts separate, so pooled AUROC is easy and within-cohort AUROC is the honest metric.
Calibration on held-out patients.
03_reliability_test.png · Calibration on held-out patients.
SHAP of the final TLS model.
03_shap_any.png · SHAP of the final TLS model.
Calibration on the OOD cohorts: bulk probabilities over-call TLS on a new cohort.
04_reliability_ood.png · Calibration on the OOD cohorts: bulk probabilities over-call TLS on a new cohort.
Predicted P(TLS) on held-out Visium sections; one colour scale for all sections, capped at the 99th percentile of their spots (TLS cover ~4% of spots).
04_spot_maps.png · Predicted P(TLS) on held-out Visium sections; one colour scale for all sections, capped at the 99th percentile of their spots (TLS cover ~4% of spots).

Immunotherapy cohorts

Patients per diagnosis and endpoint coverage
diagnosisncohortsOS n / eventsPFS n / eventsresponse n / RDCR n / DCage %sex %stage %site %location %TMB-high nPD-L1 n
BLCA3471347 / 2310 / 0298 / 68298 / 1310100000271346
COREAD19020 / 0188 / 39183 / 111183 / 165010000000
ESGA3410 / 00 / 034 / 1134 / 20010000000
NSCLC6068573 / 365606 / 490571 / 236205 / 13446462900141198
SKCM34810249 / 124174 / 113330 / 138298 / 168495934596200
ccRCC11647250 / 147977 / 585765 / 254765 / 547339617520036
Studies and cohorts
diagnosiscohortnregimenospfsresponsedcrresponse_from
BLCAPUB_BLCA_Mariathasan_EGAS00001002556347anti-PD(L)13470298298RECIST
COREADImmunoMSI108anti-CTLA4+anti-PD(L)1, anti-PD(L)10106105105RECIST
COREADNipicol82anti-CTLA4+anti-PD(L)10827878RECIST
ESGAKim_PRJEB2578034anti-PD(L)1003434RECIST
NSCLCINOVA_antiPD(L)120anti-PD(L)116201313RECIST
NSCLCINOVA_antiPD(L)1+Chemo18anti-PD(L)1+chemo181899RECIST
NSCLCJung_antiPD(L)127anti-PD(L)1027270annotated R/NR
NSCLCLee_antiPD(L)1328anti-PD(L)13283283280annotated R/NR
NSCLCLuke_antiPD(L)134anti-PD(L)134342828RECIST
NSCLCLuke_antiPD(L)1+Chemo43anti-PD(L)1+chemo43433636RECIST
NSCLCMark_antiPD(L)170anti-PD(L)168706464RECIST
NSCLCPUB_NSCLC_Banchereau_EGAS0000100434366anti-PD(L)166666655RECIST, annotated R/NR
SKCMAuslander_antiPD15anti-CTLA4, anti-CTLA4+anti-PD(L)10050annotated R/NR
SKCMFreeman_antiCTLA4+antiPD126anti-CTLA4, anti-CTLA4+anti-PD(L)1, anti-PD(L)100260annotated R/NR
SKCMGide_antiCTLA4+antiPD173anti-CTLA4+anti-PD(L)1, anti-PD(L)173737373RECIST
SKCMHugo_antiPD119anti-PD(L)11901919RECIST
SKCMKhan_antiPD114anti-PD(L)114000–
SKCMLiang_antiCTLA417anti-CTLA4, anti-PD(L)11701717RECIST
SKCMLiu_antiPD167anti-PD(L)167676565RECIST
SKCMRiaz_antiPD125anti-PD(L)12502323RECIST
SKCMRibaz_antiCTLA468anti-CTLA4, anti-CTLA4+anti-PD(L)1, anti-PD(L)1, sequential anti-CTLA4/anti-PD(L)1006868RECIST
SKCMVanAllen_antiCTLA434anti-CTLA434343433RECIST, annotated R/NR
ccRCCCheckMates181anti-PD(L)1181181172172RECIST
ccRCCJAVELIN354anti-PD(L)1+antiangiogenic035400–
ccRCCPUB_RCC_VanAllen_phs001493_Batch116anti-PD(L)116161616RECIST
ccRCCPUB_RCC_VanAllen_phs001493_Batch216anti-CTLA4+anti-PD(L)1, anti-PD(L)116161616RECIST
ccRCCPUB_ccRCC_Immotion150173anti-PD(L)1, anti-PD(L)1+antiangiogenic00164164RECIST
ccRCCPUB_ccRCC_Immotion151387anti-PD(L)1+antiangiogenic0387362362RECIST
ccRCCRNDonly_WU_ccRCC_RCCTC37anti-CTLA4+anti-PD(L)137233535RECIST
Spearman correlation of our score with each signature, within diagnosis
diagnosisCabrita (TLS_SKCM)12-chemokine (TLS_Chem)TLS imprint (Meylan 2022)
BLCA0.6200.6200.830
COREAD0.5400.2100.640
ESGA0.4900.2400.720
NSCLC0.6400.5200.690
SKCM0.5500.5700.750
ccRCC0.3500.5400.750

UMAP of ICI-treated samples (interactive)

Shown: 1,679 of 2,689 ICI-treated samples: studies whose data-use terms do not allow sharing per-patient values are left out here (they are in every aggregate table above). Embedding computed on all samples: log2(TPM+1) of the 2,000 most variable genes, standardised, 50 principal components, UMAP. Samples group mainly by study; colour by cohort shows the batch structure that within-cohort z-scoring and cohort strata remove from the outcome models.

Association with outcome

HR (OS, PFS) or OR (response, DCR) per 1 SD, adjusted; bold when the 95% CI excludes 1. HR < 1 means longer survival, OR > 1 more responses.

endpointdiagnosisTLS model (ours)12-chemokine (TLS_Chem)Cabrita (TLS_SKCM)TLS imprint (Meylan 2022)
OSBLCA0.90 [0.79, 1.03]0.88 [0.78, 1.00]0.99 [0.86, 1.15]0.95 [0.83, 1.08]
OSCOREAD––––
OSESGA––––
OSNSCLC0.92 [0.83, 1.02]0.82 [0.74, 0.91]0.90 [0.81, 1.00]0.88 [0.79, 0.98]
OSSKCM0.73 [0.59, 0.90]0.67 [0.55, 0.81]0.72 [0.58, 0.89]0.69 [0.58, 0.83]
OSccRCC1.07 [0.92, 1.24]1.06 [0.91, 1.24]0.87 [0.72, 1.05]1.08 [0.91, 1.27]
OSAll0.92 [0.86, 0.99]0.86 [0.80, 0.91]0.90 [0.84, 0.97]0.91 [0.85, 0.97]
PFSBLCA––––
PFSCOREAD0.82 [0.60, 1.12]0.87 [0.63, 1.18]0.98 [0.72, 1.35]1.01 [0.74, 1.38]
PFSESGA––––
PFSNSCLC0.93 [0.85, 1.02]0.81 [0.75, 0.89]0.88 [0.80, 0.97]0.89 [0.81, 0.98]
PFSSKCM0.93 [0.77, 1.14]0.75 [0.61, 0.91]0.73 [0.59, 0.92]0.77 [0.64, 0.92]
PFSccRCC0.93 [0.86, 1.01]0.93 [0.86, 1.01]0.92 [0.83, 1.01]0.94 [0.87, 1.01]
PFSAll0.94 [0.89, 0.99]0.87 [0.82, 0.92]0.90 [0.85, 0.96]0.91 [0.86, 0.96]
ResponseBLCA1.06 [0.82, 1.39]1.26 [0.96, 1.66]0.82 [0.59, 1.12]0.93 [0.71, 1.21]
ResponseCOREAD1.05 [0.76, 1.46]1.24 [0.89, 1.71]1.33 [0.94, 1.88]0.94 [0.67, 1.30]
ResponseESGA1.43 [0.65, 3.16]6.00 [1.57, 23.01]0.89 [0.43, 1.83]1.39 [0.61, 3.15]
ResponseNSCLC1.06 [0.89, 1.26]1.41 [1.17, 1.69]1.13 [0.95, 1.35]1.09 [0.91, 1.30]
ResponseSKCM1.04 [0.82, 1.32]1.29 [1.01, 1.64]1.13 [0.88, 1.45]1.25 [0.98, 1.60]
ResponseccRCC1.30 [1.11, 1.53]1.29 [1.10, 1.51]1.18 [0.98, 1.42]1.28 [1.08, 1.52]
ResponseAll1.15 [1.05, 1.26]1.33 [1.21, 1.46]1.11 [1.01, 1.23]1.15 [1.04, 1.26]
DCRBLCA1.30 [1.04, 1.64]1.37 [1.08, 1.72]1.20 [0.94, 1.53]1.16 [0.92, 1.47]
DCRCOREAD1.24 [0.75, 2.04]0.98 [0.60, 1.61]1.33 [0.78, 2.26]1.08 [0.66, 1.76]
DCRESGA1.96 [0.86, 4.44]2.14 [0.97, 4.70]1.18 [0.59, 2.35]1.99 [0.87, 4.54]
DCRNSCLC0.95 [0.70, 1.30]1.06 [0.77, 1.46]1.20 [0.85, 1.67]1.17 [0.86, 1.60]
DCRSKCM1.01 [0.78, 1.30]1.26 [0.98, 1.62]1.19 [0.91, 1.55]1.13 [0.88, 1.45]
DCRccRCC0.97 [0.82, 1.15]1.11 [0.94, 1.30]1.15 [0.95, 1.38]1.02 [0.87, 1.21]
DCRAll1.08 [0.97, 1.20]1.19 [1.07, 1.32]1.17 [1.04, 1.31]1.10 [0.99, 1.22]

Discrimination: ours vs each signature

ΔC-index or ΔAUC of the model with our score minus the model with the signature, same patients; bold when the bootstrap CI excludes 0.

endpointdiagnosis12-chemokine (TLS_Chem)Cabrita (TLS_SKCM)TLS imprint (Meylan 2022)covariates only
OSBLCA+0.001 [-0.022, +0.029]+0.019 [+0.004, +0.069]+0.012 [-0.001, +0.036]+0.030 [+0.011, +0.057]
OSNSCLC-0.045 [-0.076, -0.004]-0.017 [-0.058, +0.024]-0.016 [-0.048, +0.012]+0.013 [-0.011, +0.043]
OSSKCM-0.025 [-0.052, +0.014]+0.008 [-0.014, +0.041]-0.013 [-0.032, +0.023]+0.052 [-0.004, +0.090]
OSccRCC-0.002 [-0.030, +0.018]+0.016 [-0.031, +0.052]-0.008 [-0.033, +0.024]+0.003 [-0.016, +0.036]
OSAll-0.020 [-0.039, +0.001]+0.002 [-0.012, +0.021]+0.002 [-0.008, +0.022]+0.022 [+0.002, +0.043]
PFSCOREAD+0.007 [-0.043, +0.041]+0.032 [-0.067, +0.051]+0.008 [-0.063, +0.057]+0.013 [-0.005, +0.057]
PFSNSCLC-0.047 [-0.086, -0.019]-0.023 [-0.051, +0.001]-0.007 [-0.056, +0.013]+0.019 [-0.010, +0.046]
PFSSKCM-0.042 [-0.070, +0.000]-0.027 [-0.049, +0.003]-0.035 [-0.054, -0.003]-0.001 [-0.007, +0.024]
PFSccRCC-0.009 [-0.020, +0.004]-0.012 [-0.029, +0.004]-0.005 [-0.015, +0.004]+0.005 [-0.014, +0.018]
PFSAll-0.021 [-0.032, -0.006]-0.015 [-0.034, -0.005]-0.006 [-0.014, +0.005]-0.000 [-0.018, +0.017]
ResponseBLCA-0.013 [-0.070, +0.011]+0.032 [-0.078, +0.102]+0.047 [-0.024, +0.113]+0.041 [-0.005, +0.081]
ResponseCOREAD-0.008 [-0.058, +0.015]-0.025 [-0.050, +0.005]+0.003 [-0.021, +0.015]+0.001 [-0.006, +0.028]
ResponseESGA-0.217 [-0.270, -0.102]+0.126 [-0.107, +0.148]+0.024 [-0.052, +0.126]+0.071 [+0.010, +0.198]
ResponseNSCLC-0.034 [-0.063, -0.016]-0.015 [-0.037, +0.017]-0.004 [-0.023, +0.006]+0.004 [-0.008, +0.027]
ResponseSKCM-0.009 [-0.029, +0.013]-0.001 [-0.013, +0.013]-0.007 [-0.014, +0.008]-0.003 [-0.002, +0.012]
ResponseccRCC-0.001 [-0.010, +0.020]+0.019 [+0.002, +0.031]+0.006 [-0.020, +0.014]+0.018 [+0.005, +0.041]
ResponseAll-0.014 [-0.022, -0.006]+0.003 [-0.002, +0.005]+0.001 [-0.002, +0.004]+0.006 [+0.001, +0.013]
DCRBLCA-0.004 [-0.049, +0.047]+0.024 [-0.016, +0.061]+0.023 [-0.006, +0.044]+0.074 [+0.020, +0.130]
DCRCOREAD+0.016 [-0.035, +0.080]-0.006 [-0.034, +0.036]+0.001 [-0.030, +0.042]+0.011 [-0.005, +0.066]
DCRESGA-0.068 [-0.218, +0.121]+0.061 [-0.082, +0.220]+0.021 [-0.172, +0.125]+0.107 [+0.032, +0.269]
DCRNSCLC+0.005 [-0.030, +0.028]+0.002 [-0.025, +0.023]-0.004 [-0.029, +0.031]+0.006 [-0.005, +0.037]
DCRSKCM-0.006 [-0.038, +0.017]-0.003 [-0.017, +0.009]+0.001 [-0.017, +0.010]-0.000 [-0.007, +0.019]
DCRccRCC-0.006 [-0.010, +0.010]-0.001 [-0.015, +0.016]-0.001 [-0.007, +0.008]+0.000 [-0.001, +0.014]
DCRAll-0.006 [-0.008, +0.000]-0.003 [-0.005, +0.001]-0.001 [-0.003, +0.002]+0.001 [+0.000, +0.004]

Each score vs the confounders-only model:

endpointdiagnosis12-chemokine (TLS_Chem)Cabrita (TLS_SKCM)TLS imprint (Meylan 2022)TLS model (ours)
OSBLCA+0.029 [+0.007, +0.047]+0.011 [-0.021, +0.034]+0.018 [-0.006, +0.046]+0.030 [+0.011, +0.057]
OSNSCLC+0.057 [+0.001, +0.077]+0.030 [+0.001, +0.061]+0.029 [+0.003, +0.062]+0.013 [-0.011, +0.043]
OSSKCM+0.077 [+0.022, +0.110]+0.043 [-0.002, +0.069]+0.065 [+0.004, +0.087]+0.052 [-0.004, +0.090]
OSccRCC+0.004 [-0.006, +0.044]-0.013 [-0.023, +0.027]+0.011 [-0.016, +0.051]+0.003 [-0.016, +0.036]
OSAll+0.042 [+0.015, +0.059]+0.020 [-0.008, +0.038]+0.019 [+0.000, +0.039]+0.022 [+0.002, +0.043]
PFSCOREAD+0.007 [-0.011, +0.068]-0.019 [-0.028, +0.076]+0.005 [-0.015, +0.072]+0.013 [-0.005, +0.057]
PFSNSCLC+0.066 [+0.031, +0.102]+0.043 [+0.014, +0.064]+0.027 [-0.002, +0.067]+0.019 [-0.010, +0.046]
PFSSKCM+0.041 [-0.001, +0.078]+0.025 [-0.003, +0.064]+0.033 [+0.000, +0.065]-0.001 [-0.007, +0.024]
PFSccRCC+0.014 [-0.008, +0.031]+0.016 [-0.009, +0.036]+0.009 [-0.009, +0.029]+0.005 [-0.014, +0.018]
PFSAll+0.021 [+0.005, +0.043]+0.015 [+0.002, +0.036]+0.005 [-0.015, +0.029]-0.000 [-0.018, +0.017]
ResponseBLCA+0.054 [+0.012, +0.110]+0.009 [-0.027, +0.087]-0.006 [-0.040, +0.040]+0.041 [-0.005, +0.081]
ResponseCOREAD+0.009 [-0.007, +0.058]+0.026 [-0.000, +0.074]-0.002 [-0.003, +0.039]+0.001 [-0.006, +0.028]
ResponseESGA+0.289 [+0.211, +0.362]-0.055 [-0.045, +0.178]+0.047 [+0.002, +0.184]+0.071 [+0.010, +0.198]
ResponseNSCLC+0.038 [+0.028, +0.077]+0.019 [-0.013, +0.047]+0.008 [-0.004, +0.041]+0.004 [-0.008, +0.027]
ResponseSKCM+0.006 [-0.004, +0.030]-0.002 [-0.004, +0.014]+0.004 [-0.003, +0.016]-0.003 [-0.002, +0.012]
ResponseccRCC+0.019 [+0.003, +0.030]-0.001 [-0.006, +0.020]+0.012 [+0.003, +0.049]+0.018 [+0.005, +0.041]
ResponseAll+0.020 [+0.009, +0.030]+0.003 [+0.000, +0.011]+0.005 [+0.000, +0.013]+0.006 [+0.001, +0.013]
DCRBLCA+0.078 [+0.024, +0.102]+0.050 [-0.001, +0.099]+0.051 [+0.007, +0.094]+0.074 [+0.020, +0.130]
DCRCOREAD-0.005 [-0.017, +0.039]+0.017 [-0.004, +0.050]+0.010 [-0.016, +0.039]+0.011 [-0.005, +0.066]
DCRESGA+0.175 [+0.068, +0.328]+0.046 [-0.026, +0.237]+0.086 [-0.015, +0.234]+0.107 [+0.032, +0.269]
DCRNSCLC+0.001 [-0.007, +0.035]+0.005 [-0.004, +0.031]+0.011 [-0.002, +0.043]+0.006 [-0.005, +0.037]
DCRSKCM+0.005 [-0.005, +0.035]+0.003 [-0.006, +0.016]-0.002 [-0.001, +0.019]-0.000 [-0.007, +0.019]
DCRccRCC+0.006 [-0.004, +0.013]+0.001 [-0.005, +0.016]+0.001 [-0.004, +0.012]+0.000 [-0.001, +0.014]
DCRAll+0.007 [+0.002, +0.010]+0.004 [-0.000, +0.008]+0.002 [+0.000, +0.006]+0.001 [+0.000, +0.004]
OS: left, adjusted HR / OR per SD; right, Δ of ours vs each signature.
05_forest_OS.png · OS: left, adjusted HR / OR per SD; right, Δ of ours vs each signature.
PFS: left, adjusted HR / OR per SD; right, Δ of ours vs each signature.
05_forest_PFS.png · PFS: left, adjusted HR / OR per SD; right, Δ of ours vs each signature.
Response: left, adjusted HR / OR per SD; right, Δ of ours vs each signature.
05_forest_Response.png · Response: left, adjusted HR / OR per SD; right, Δ of ours vs each signature.
DCR: left, adjusted HR / OR per SD; right, Δ of ours vs each signature.
05_forest_DCR.png · DCR: left, adjusted HR / OR per SD; right, Δ of ours vs each signature.

TMB-high + PD-L1 subset

Patients with both a TMB call and PD-L1 IHC (271 BLCA, 106 NSCLC). Base model = confounders + TMB-high + PD-L1.

endpointdiagnosisTLS model (ours)12-chemokine (TLS_Chem)Cabrita (TLS_SKCM)TLS imprint (Meylan 2022)
OSBLCA0.83 [0.71, 0.96]0.81 [0.69, 0.94]0.83 [0.70, 0.99]0.89 [0.78, 1.03]
OSNSCLC0.91 [0.63, 1.32]0.89 [0.57, 1.41]0.98 [0.68, 1.42]0.88 [0.63, 1.25]
OSAll0.84 [0.73, 0.97]0.82 [0.71, 0.95]0.88 [0.76, 1.03]0.90 [0.80, 1.03]
PFSBLCA––––
PFSNSCLC0.90 [0.66, 1.22]0.81 [0.57, 1.15]0.90 [0.65, 1.24]0.81 [0.60, 1.10]
PFSAll0.90 [0.66, 1.22]0.81 [0.57, 1.15]0.90 [0.65, 1.24]0.81 [0.60, 1.10]
ResponseBLCA1.14 [0.83, 1.56]1.22 [0.88, 1.68]0.91 [0.63, 1.33]0.94 [0.69, 1.28]
ResponseNSCLC0.61 [0.35, 1.04]0.87 [0.50, 1.51]0.68 [0.40, 1.14]0.88 [0.53, 1.46]
ResponseAll0.95 [0.74, 1.23]1.10 [0.84, 1.45]0.82 [0.61, 1.10]0.91 [0.70, 1.17]
DCRBLCA1.46 [1.11, 1.93]1.43 [1.08, 1.90]1.38 [1.02, 1.88]1.20 [0.91, 1.57]
DCRNSCLC0.72 [0.41, 1.26]0.94 [0.52, 1.73]0.73 [0.40, 1.31]1.07 [0.58, 1.98]
DCRAll1.26 [0.99, 1.61]1.32 [1.02, 1.69]1.19 [0.92, 1.55]1.16 [0.91, 1.49]
Each score over confounders + TMB-high + PD-L1
endpointdiagnosis12-chemokine (TLS_Chem)Cabrita (TLS_SKCM)TLS imprint (Meylan 2022)TLS model (ours)
OSBLCA+0.024 [-0.000, +0.066]+0.015 [+0.000, +0.052]+0.014 [-0.004, +0.046]+0.021 [+0.006, +0.056]
OSNSCLC+0.001 [-0.046, +0.105]+0.006 [-0.017, +0.066]+0.001 [-0.021, +0.077]+0.003 [-0.028, +0.056]
OSAll+0.034 [-0.003, +0.058]+0.020 [+0.001, +0.034]+0.019 [-0.006, +0.039]+0.033 [-0.004, +0.052]
PFSNSCLC+0.002 [-0.021, +0.104]+0.027 [-0.015, +0.150]+0.022 [-0.033, +0.096]+0.023 [-0.024, +0.103]
PFSAll+0.002 [-0.021, +0.104]+0.027 [-0.015, +0.150]+0.022 [-0.033, +0.096]+0.023 [-0.024, +0.103]
ResponseBLCA+0.022 [-0.004, +0.045]-0.000 [-0.014, +0.030]+0.001 [-0.008, +0.035]+0.015 [-0.007, +0.040]
ResponseNSCLC+0.009 [-0.007, +0.062]+0.028 [-0.004, +0.108]+0.009 [-0.004, +0.056]+0.045 [+0.001, +0.114]
ResponseAll+0.004 [-0.005, +0.025]+0.003 [-0.008, +0.028]+0.004 [-0.006, +0.022]-0.006 [-0.009, +0.022]
DCRBLCA+0.036 [+0.003, +0.087]+0.028 [+0.005, +0.070]+0.017 [-0.006, +0.068]+0.049 [+0.010, +0.079]
DCRNSCLC+0.009 [-0.011, +0.062]+0.027 [-0.024, +0.050]-0.002 [-0.003, +0.051]+0.024 [-0.012, +0.051]
DCRAll+0.028 [+0.003, +0.045]+0.017 [-0.006, +0.023]+0.017 [-0.001, +0.032]+0.029 [+0.009, +0.038]
OS, adjusted for TMB-high and PD-L1.
05_forest_tmb_pdl1_OS.png · OS, adjusted for TMB-high and PD-L1.
PFS, adjusted for TMB-high and PD-L1.
05_forest_tmb_pdl1_PFS.png · PFS, adjusted for TMB-high and PD-L1.
Response, adjusted for TMB-high and PD-L1.
05_forest_tmb_pdl1_Response.png · Response, adjusted for TMB-high and PD-L1.
DCR, adjusted for TMB-high and PD-L1.
05_forest_tmb_pdl1_DCR.png · DCR, adjusted for TMB-high and PD-L1.

Added value over 12-chemokine

Δ (bigger − smaller nested model) with bootstrap CI, then the likelihood-ratio p. Bold: p < 0.05, uncorrected. Comparisons a–e are defined in Methods.

endpointdiagnosisabb vs acdee vs d
OSBLCA+0.001 [-0.003, +0.026] · p=0.81+0.010 [-0.001, +0.063] · p=0.051+0.009 [-0.003, +0.059] · p=0.015+0.021 [+0.006, +0.056] · p=0.013+0.000 [-0.002, +0.023] · p=0.52+0.021 [+0.001, +0.063] · p=0.0072+0.021 [+0.001, +0.056] · p=0.0021
OSNSCLC+0.000 [-0.012, +0.008] · p=0.84-0.000 [-0.016, +0.012] · p=0.97-0.000 [-0.010, +0.011] · p=0.86+0.003 [-0.028, +0.056] · p=0.63-0.011 [-0.020, +0.066] · p=0.78+0.000 [-0.037, +0.069] · p=0.56+0.011 [-0.051, +0.059] · p=0.3
OSSKCM-0.002 [-0.012, +0.016] · p=0.34+0.006 [-0.016, +0.019] · p=0.31+0.008 [-0.013, +0.008] · p=0.23––––
OSccRCC-0.001 [-0.016, +0.030] · p=0.61+0.003 [-0.015, +0.059] · p=0.048+0.004 [-0.014, +0.042] · p=0.016––––
OSAll-0.000 [-0.003, +0.004] · p=0.74+0.004 [-0.002, +0.017] · p=0.25+0.005 [-0.002, +0.016] · p=0.1+0.033 [-0.004, +0.052] · p=0.016+0.002 [-0.003, +0.017] · p=0.47+0.015 [+0.001, +0.049] · p=0.025+0.013 [-0.006, +0.036] · p=0.0089
PFSCOREAD+0.003 [-0.018, +0.045] · p=0.27+0.005 [-0.017, +0.050] · p=0.25+0.002 [-0.004, +0.043] · p=0.22––––
PFSNSCLC-0.001 [-0.006, +0.004] · p=0.5-0.001 [-0.016, +0.008] · p=0.76+0.001 [-0.011, +0.005] · p=0.78+0.023 [-0.024, +0.103]+0.003 [-0.013, +0.073]+0.001 [-0.012, +0.089]-0.001 [-0.010, +0.034]
PFSSKCM+0.011 [-0.005, +0.041] · p=0.19+0.009 [-0.008, +0.040] · p=0.39-0.002 [-0.006, +0.013] · p=0.71––––
PFSccRCC-0.006 [-0.014, +0.010] · p=0.41+0.002 [-0.018, +0.028] · p=0.063+0.007 [-0.005, +0.026] · p=0.027––––
PFSAll+0.001 [-0.002, +0.006]+0.002 [-0.002, +0.010]+0.001 [-0.001, +0.005]+0.023 [-0.024, +0.103]+0.003 [-0.013, +0.073]+0.001 [-0.012, +0.089]-0.001 [-0.010, +0.034]
ResponseBLCA-0.002 [-0.009, +0.066] · p=0.41+0.006 [-0.005, +0.078] · p=0.23+0.008 [-0.004, +0.048] · p=0.13+0.015 [-0.007, +0.040] · p=0.42-0.001 [-0.005, +0.021] · p=0.97+0.019 [-0.001, +0.053] · p=0.099+0.019 [-0.000, +0.047] · p=0.032
ResponseCOREAD+0.001 [-0.001, +0.017] · p=0.95+0.003 [-0.004, +0.023] · p=0.96+0.002 [-0.003, +0.011] · p=0.78––––
ResponseESGA+0.000 [-0.016, +0.062] · p=0.99-0.008 [-0.034, +0.074] · p=0.97-0.008 [-0.019, +0.023] · p=0.82––––
ResponseNSCLC+0.005 [-0.001, +0.017] · p=0.17+0.007 [-0.002, +0.028] · p=0.27+0.002 [-0.001, +0.014] · p=0.39+0.045 [+0.001, +0.114] · p=0.052+0.036 [-0.009, +0.076] · p=0.037+0.035 [-0.001, +0.089] · p=0.11-0.001 [-0.005, +0.024] · p=0.8
ResponseSKCM+0.002 [-0.003, +0.022] · p=0.3+0.006 [+0.000, +0.043] · p=0.4+0.004 [-0.003, +0.034] · p=0.39––––
ResponseccRCC+0.003 [-0.000, +0.020] · p=0.078+0.007 [+0.000, +0.020] · p=0.092+0.003 [-0.003, +0.009] · p=0.2––––
ResponseAll-0.000 [-0.000, +0.001] · p=0.78+0.000 [-0.000, +0.005] · p=0.41+0.001 [-0.000, +0.006] · p=0.19-0.006 [-0.009, +0.022] · p=0.72+0.004 [-0.007, +0.030] · p=0.26+0.008 [+0.001, +0.049] · p=0.12+0.005 [-0.000, +0.029] · p=0.085
DCRBLCA+0.007 [-0.002, +0.046] · p=0.48+0.006 [-0.003, +0.065] · p=0.44-0.002 [-0.008, +0.028] · p=0.28+0.049 [+0.010, +0.079] · p=0.0064+0.014 [-0.003, +0.025] · p=0.18+0.019 [-0.005, +0.051] · p=0.071+0.005 [-0.005, +0.038] · p=0.062
DCRCOREAD+0.020 [-0.013, +0.094] · p=0.37+0.021 [-0.008, +0.085] · p=0.52+0.001 [-0.015, +0.046] · p=0.48––––
DCRESGA+0.014 [+0.005, +0.113] · p=0.28+0.007 [-0.002, +0.136] · p=0.35-0.007 [-0.045, +0.055] · p=0.34––––
DCRNSCLC+0.007 [-0.005, +0.032] · p=0.56+0.010 [-0.004, +0.031] · p=0.71+0.003 [-0.004, +0.020] · p=0.56+0.024 [-0.012, +0.051] · p=0.24+0.020 [-0.010, +0.053] · p=0.19+0.012 [-0.002, +0.102] · p=0.39-0.008 [-0.007, +0.067] · p=0.71
DCRSKCM+0.004 [-0.001, +0.032] · p=0.21+0.005 [-0.001, +0.042] · p=0.43+0.001 [-0.001, +0.028] · p=0.72––––
DCRccRCC+0.003 [-0.003, +0.014] · p=0.23+0.006 [-0.002, +0.017] · p=0.13+0.003 [-0.002, +0.012] · p=0.11––––
DCRAll+0.000 [-0.000, +0.002] · p=0.58+0.002 [+0.000, +0.005] · p=0.4+0.001 [-0.000, +0.004] · p=0.22+0.029 [+0.009, +0.038] · p=0.062+0.004 [-0.008, +0.015] · p=0.6+0.010 [-0.003, +0.035] · p=0.28+0.006 [-0.001, +0.029] · p=0.13

Our score adds nothing over the 12-chemokine signature (a, d). On the TMB + PD-L1 subset it adds to TMB and PD-L1 alone (c), mostly in bladder cancer. The interaction term (b vs a, e vs d) reaches p < 0.05 in bladder cancer and ccRCC OS: patients high on both scores fare better than either score predicts. The subset and the bladder cohort are largely the same IMvigor210 patients, so these are not independent confirmations.

Comparisons a and b, all patients.
05_added_value_chem.png · Comparisons a and b, all patients.
Comparisons c–e, TMB-high + PD-L1 subset.
05_added_value_tmb_pdl1_chem.png · Comparisons c–e, TMB-high + PD-L1 subset.

Limitations

  • Bulk within one cohort is weak (AUROC about 0.55–0.65 for every model family, signatures included); bulk probabilities over-call TLS on a new cohort, so use the ranking there.
  • No maturity output: the maturity head showed no signal.
  • For immunotherapy outcome the model is at best equal to the 12-chemokine signature.
  • Bootstrap uses 20 replicates: intervals are rough and occasionally do not contain the point estimate.
  • No correction for multiplicity across diagnoses × endpoints × comparisons; the interaction finding is a hypothesis.
  • Pooled PFS and the TMB + PD-L1 PFS models needed a small ridge penalty to converge; no likelihood-ratio test is reported for them.
  • Confounder coverage is uneven: age, stage and site are missing for most studies; TMB and PD-L1 exist for two diagnoses only.
  • Several studies carry restricted-use terms; this report holds aggregates only and is not for public release.