"""Front Immunol 2025, doi 10.3389/fimmu.2025.1713225 (GSE309566): CDR3 beta of sorted CD4+ T cells from 13 healthy donors, PBMC cultured 10 days with one peptide (influenza A HA 306-318 or
EBV EBNA 515-528), restimulated, sorted CD134+CD137+ (AIM). 24 MiXCR clonotype tables (`VF_<donor>_{HA,EBNA}`), tab separated; donor and antigen from the file name. Beta chain only (no alpha).
These are the stimulated (POS) libraries; the unstimulated NEG libraries and the unsorted `Total_Vf` repertoires of the GEO series are not in the downloaded files.
Each table lists every clonotype of the sorted population including low-frequency bystanders, so only clonotypes with `Proportion` >= 0.001 (0.1% of the sample's clonotype counts) are kept
(about 100 to 200 per file, 58 to 89% of each sample); the paper itself reports a few clones carrying about 60% of the cells. The threshold is arbitrary and is not the paper's.
53 clonotypes above the threshold (1.6%) are dropped because the CDR3 does not start with the conserved C (51 begin RASS with nucleotides CGT, 2 begin with Y): the first base looks mis-read, not corrected here.
Clonotypes with the same V, J and CDR3 amino acid sequence (different nucleotides) are one record. `Clones` is a count of unknown unit (reads or UMIs, unverified), so `cells` is left empty.
V.name can list several genes separated by commas (tied call, about half of the clonotypes): TRBV is then left empty rather than picking one.
Epitope is the residue range as printed in the paper ("HA 306-318 (residue range)"), not a sequence: the paper's HA sequence (R) differs from the usual one (K), unresolved. Level "epitope".
Donor HLA-DRB1 typing (two alleles, Table1.docx) is in `context`; restriction is not mapped per clonotype, so `restriction` is empty."""
import glob
import re
import zipfile
import pandas as pd
from atlas import SRC

PEP = {"HA": "HA 306-318 (residue range)", "EBNA": "EBNA 515-528 (residue range)"}
ANT = {"HA": "influenza A hemagglutinin", "EBNA": "EBV EBNA1"}
ORG = {"HA": "influenza A virus", "EBNA": "Epstein-Barr virus"}
MIN = 0.001


def hla():
    x = zipfile.ZipFile(SRC / "Lhomme2025/Table1.docx").read("word/document.xml").decode()
    rows = [["".join(re.findall(r"<w:t[^>]*>([^<]*)</w:t>", c)) for c in re.findall(r"<w:tc>.*?</w:tc>", r, flags=re.S)] for r in re.findall(r"<w:tr[ >].*?</w:tr>", x, flags=re.S)]
    return {r[0]: f"HLA-DRB1 {r[1]} / {r[2]}" for r in rows if re.fullmatch(r"\d{4}", r[0])}


def parse():
    typing, out = hla(), []
    for f in sorted(glob.glob(str(SRC / "Lhomme2025/*_VF_*.txt.gz"))):
        donor, ag = re.search(r"_VF_(\d+)_(HA|EBNA)\.txt", f).groups()
        d = pd.read_csv(f, sep="\t")
        d = d[(d.Proportion >= MIN) & d["CDR3.aa"].str.startswith("C")].rename(columns={"CDR3.aa": "CDR3b", "V.name": "TRBV", "J.name": "TRBJ"})[["CDR3b", "TRBV", "TRBJ"]].drop_duplicates()
        d["TRBV"] = d.TRBV.where(~d.TRBV.str.contains(","))
        out.append(d.assign(donor=donor, epitope=PEP[ag], antigen=ANT[ag], organism=ORG[ag],
                            context=f"healthy donor, {typing[donor]}; PBMC with {ag} peptide 10 days, restimulated, CD134+CD137+ sorted CD4+"))
    return pd.concat(out).assign(source="Lhomme 2025 (Front Immunol)", study="GEO:GSE309566", species="human", cd4_evidence="sorted CD4+", annotation_level="epitope",
                                 specificity_evidence=f"peptide expansion then CD134+CD137+ sort (AIM); clonotypes with frequency >= {MIN:.1%} of the sample only; bystanders not excluded")
