Intersect CMV ECOcluster TCRs with repertoires to predict CMV status and HLA type.
Published
August 10, 2026
1 Takeaways from this post
The CMV ECOcluster is a very good predictor of CMV status, even without accounting for donor HLA type
But donor HLA type does matter! Asian or Pacific Islander donors have fewer CMV ECOcluster TCRs.
Among CMV+ donors, the CMV ECOcluster can be used to predict donor HLA allele status for several alleles with high sensitivity and specificity
Those HLA “models” could be used as a seed for stronger, generalized models
Code
# useful importsimport pandas as pdfrom matplotlib import pyplot as pltimport itablesimport seaborn as snsfrom cmvividly.plots.style import set_styleset_style()import itablesitables.init_notebook_mode()#statsfrom scipy.stats import mannwhitneyu
2 Load previously saved files related to the “Emerson” datasets
The TCR repertoires from the two “Emerson” cohorts are available through Adaptive’s ImmuneAccess portal. I downloaded the data, extracted the sample metadata and intersected the repertoire TCRs with the CMV ECOcluster, in this notebook. This intersection makes no attempt to account for donor HLA type.
Let’s load those processed files and prepare them for analysis.
Code
from cmvividly.data.access import load_emerson_metadatapdf_sample_metadata = load_emerson_metadata()print("'Emerson' cohort breakdown by CMV status:")pd.crosstab(pdf_sample_metadata.cohort, pdf_sample_metadata.cmv_status)
'Emerson' cohort breakdown by CMV status:
Loading ITables v2.9.1 from the init_notebook_mode cell...
(need help?)
3.1 Visualize the intersection by cohort and CMV status
Visualize the difference in this intersection between CMV+ and CMV- donors. Three metrics: * match count (n_matches): the number of TCRs in the sample that match the CMV ECOcluster * breadth: the fraction of TCRs in the sample that match the CMV ECOcluster * depth: the sum of productive frequencies of TCRs in the sample that match the CMV ECOcluster
So, after accounting for repertoire depth in one of two ways, the ECOcluster is a very good predictor of CMV status, even though we haven’t accounted for donor HLA type at all.
4.1 Break down performance by race
But that doesn’t mean HLA doesn’t matter, even for CMV diagnosis! Race is a loose but useful proxy for HLA type. The CMV ECOcluster was built on repertoires from a wide variety of donors, some explicitly sourced to increase donor diversity. Nevertheless, well over half were Caucasian. Let’s see how these donors break down by the race reported in the metadata:
Those values are straight from the ImmuneAccess file. I’m not sure what race “0” means, so I’ll leave that out. I’ll also leave out the groups with very few donors.
We might expect to see the classifier do better on Caucasians than on other groups, because they share more alleles with the repertoires ECOclusters were built on. Let’s take a look.
Visually, it looks like, among CMV+ donors, breadth, depth and # matches are all lower in the Asian or Pacific Islander group than in the other groups. Let’s test for significance with a two-sided Mann-Whitney U test.
Yes, these differences are highly significant, particularly for match count and breadth. In the preprint, we took great pains to account for those differences, using inferred HLA types on all the donors and comparing breadths against reference distributions for donors with the associated allele.
Let’s take a look at ROC curves within each group:
We do markedly worse for the Unknown racial group due to a number of CMV- donors with very high breadth. There are a lot of people in that group, so the difference isn’t likely due to chance. More likely, those donors have HLA alleles whose CMV-COclusters aren’t as well differentiated w.r.t. CMV status and lack other alleles that are better differentiated.
Also, from the boxplots and MWU tests above, we also know that, if we throw all those donors together, API CMV+ donors will be less well-separated from CMV- donors of other races.
5 Infer donor CMV+ donor HLA type from the TCR repertoire
Can we get something useful out of the HLA-bound nature of the CMV TCRs? Can we use it to infer the status of CMV+ donors with respect to the HLA alleles present in the CMV ECOcluster?
If we consider two CMV+ donors, one with HLA allele A*02:01 and one without, only the first donor should have A*02:01-associated TCRs responding to CMV. Since the CMV ECOcluster records the HLA allele associated with each TCR, we can use the A*02:01-associated CMV ECOcluster TCRs in a CMV+ donor’s repertoire to predict whether that donor has A*02:01.
Limitations:
All we’ve got is Class I HLA type, for a subset of donors, so we’re entirely blind to Class II
(I think the full HLA types for these donors might be floating around somewhere? If you know how to get them, let me know and I’ll redo all this!)
The HLA metadata has values like HLA-A*01, while the HLA-COclusters in the CMV ECOcluster are associated with alleles like A*01:01. My workaround here will be to add :01 to the end of the HLA metadata values and see if any HLA-COclusters match. That’s a bit of a hack, and I might be missing some modelable alleles this way, but it demonstrates the idea.
Code
pdf_sample_metadata_withhla = pdf_sample_metadata[pdf_sample_metadata.hla_class_i.notnull()]pdf_sample_metadata_withhla_cmvpos = pdf_sample_metadata_withhla[pdf_sample_metadata_withhla.cmv_status ==1]print(f"Number of CMV+ donors with HLA Class I data: {len(pdf_sample_metadata_withhla_cmvpos)}")all_alleles =set()for hla_str in pdf_sample_metadata_withhla_cmvpos.hla_class_i: alleles = hla_str.split(",") all_alleles.update([x for x in alleles if x !="HLA MHC Class I"]) # there's some malformed metadata in there.print(f"HLA Class I alleles present among CMV+ donors: {len(all_alleles)}")alleles =sorted(all_alleles)pos_counts = []neg_counts = []for allele insorted(all_alleles): pdf_sample_metadata_withhla[allele] = pdf_sample_metadata_withhla.hla_class_i.apply(lambda x: 1if allele instr(x).split(",") else0) pos_counts.append(pdf_sample_metadata_withhla[(pdf_sample_metadata_withhla[allele] ==1) & (pdf_sample_metadata_withhla.cmv_status ==1)].shape[0]) neg_counts.append(pdf_sample_metadata_withhla[(pdf_sample_metadata_withhla[allele] ==1) & (pdf_sample_metadata_withhla.cmv_status ==0)].shape[0])pdf_pos_neg_counts = pd.DataFrame({"allele": sorted(all_alleles),"pos_count": pos_counts,"neg_count": neg_counts})f, ax = plt.subplots() sns.histplot(data=pdf_pos_neg_counts, x="pos_count", ax=ax, bins=20)ax.set_title("CMV+ donor counts per Class I allele")pass
Number of CMV+ donors with HLA Class I data: 274
HLA Class I alleles present among CMV+ donors: 59
A lot of those alleles have very few allele+ donors among the CMV+ donors. Luckily, we don’t really need to train a model! We just need enough donors to assess breadth as a predictor of allele status.
Let’s require at least 10 CMV+ donors with that allele to assess breadth as a predictor of allele status.
Code
alleles_enough_cmvpos = pdf_pos_neg_counts[pdf_pos_neg_counts.pos_count >=10].allele.tolist()print(f"Class I alleles with at least 10 CMV+ donors: {len(alleles_enough_cmvpos)}")# eliminate alleles with no associated HLA-COclusteralleles_enough_cmvpos_with_hlacocluster = [ allele for allele in alleles_enough_cmvpos if allele[len("HLA-"):] +":01"in pdf_tcr_matches_2026.hla.unique().tolist()]print(f"...and an associated HLA-COcluster: {len(alleles_enough_cmvpos_with_hlacocluster)}")
Class I alleles with at least 10 CMV+ donors: 28
...and an associated HLA-COcluster: 12
So, there are 12 or so alleles we can reasonably evaluate.
Let’s evaluate breadth on the associated HLA-COcluster as a predictor for having each allele.
AUROCs based on breadth and on depth are strikingly similar, with a slight advantage to breadth-based models.
Just to be sure, let’s take a look at those same “models” in CMV- donors. There should be no signal, because those donors shouldn’t have CMV-responding TCRs.
Huh! Most of the alleles are total garbage, as expected. But there’s some signal in A*01. There’s only one A*01:01 HLA-COcluster in the CMV ECOcluster, but perhaps it’s not totally “pure”… maybe it’s dominated by CMV-specific TCRs, but some TCRs also respond to other exposures.
6 Applications of HLA allele models usable on CMV+ donors
So, all but one of those “models” (HLA-B*35) has notable sensitivity at essentially perfect specificity, and they all have AUROC > 0.77. The best 6 models have >70% sensitivity at 98% specificity.
Quite likely, a number of the other alleles represented in the CMV ECOcluster have similar performance, but we don’t have enough CMV+ donors with those alleles in this dataset to assess performance. And of course we haven’t even been able to look at Class II alleles, since we didn’t have any data there.
I think the best HLA allele models, combined with the CMV ECOcluster’s ability to predict CMV status and enough public repertoires, could allow us to “pseudolabel” inferred CMV+ donors with status on those HLAs, learn signal from exposures other than CMV, and build HLA allele models that could be used on both CMV+ and CMV- donors.