starplast.cellcycle
Cell-cycle phase, and stage enrichment — kept rigorously apart, because one is measured and one is not.
Half of what this project exists to do could not be evaluated before this module. The stated aim is to
walk dataset combinations and find embeddings where location or cell-cycle stage maps onto the
structure, so that a gene landing in that structure inherits a testable prediction. Location has a
target: 3,827 hyperLOPIT compartment labels to hold out. Cell-cycle stage had none — searching all 165
node columns for anything cyclical returned only continuous expression (expr_tachy, tachyzoite FPKM,
oocyst iTRAQ ratios). There was nothing discrete to hold out, so the question could not be asked, let
alone answered.
The measured label
Xue et al. 2020 (eLife 9:e54129, PMID 32065584) sequenced single parasites and assigned each gene a cell-cycle phase from where its expression peaks along pseudotime. Supplementary file 3 gives 964 genes a phase from G1a, G1b, S, M, C. That is an independent measurement of cell-cycle behavior: it comes from single-cell expression this project does not otherwise use, and it is a label a paper committed to, not a threshold chosen here.
cellcycle_phase G1a / G1b / S / M / C 964 genes, measured
cellcycle_pseudotime 1 / 2 / 3 8,590 genes, coarser
Those files use TGGT1_ accessions — the RH strain, type I — while this project is built on ME49. The Pru differentiation files in the same paper use TGME49_. Two strains inside one supplementary set, told apart only by the accession prefix; routing through the identity layer is mandatory here, not a precaution.
The derived label, and why it is named that way
stage_enriched_derived assigns each gene the life-cycle stage its own expression is highest in. It is
useful and it is not evidence: it is a restatement of the expression columns it was computed from.
Holding it out against an embedding built on those same columns would be circular by construction, and
this project has already been bitten by exactly that. compartment fed one embedding and the cluster
battery reported its twin lopit_map and its derivations as the top held-out discoveries at V = 0.96;
held out honestly, the best of 164 runs reached mean F1 0.362. So the derived column carries _derived
in its name, the registry records which columns produced it, and search.py's circularity guard —
which measures association with the inputs rather than trusting names — will mark it derived on its own.
The naming is the cheap part. The guard is what actually protects the result.
Measured cell-cycle phase per gene, on canonical accessions.
resolve is the identity layer. Without it every TGGT1_ accession fails to join and the result is
an empty frame rather than an error, which is the failure mode this project keeps meeting.
Coarse pseudotime cluster for the whole RH gene set. Broader coverage, weaker label.
When in a CYCLE each row peaks, and how strongly, from a time course sampled around it.
Written for the Plasmodium intraerythrocytic cycle and kept here because the construction is not about either parasite: it is what a time course over a closed loop means. The columns are hours and the axis wraps -- hour 48 of one cycle is hour 0 of the next -- so the peak cannot be the largest column. Taking it that way splits a late peak between the last timepoint and the first, and it does: AMA1 and PTRAMP, textbook invasion transcripts, come out at hour 3 because a culture synchronised at invasion still carries the merozoite's mRNA.
The first Fourier harmonic gives a phase instead, which is the standard reading of a cell-cycle
transcriptome and has no ends to pile against. amplitude is that harmonic's share of the row's
total variation, so a flat or noisy profile scores near zero and can be excluded on a number
rather than on a guess.
Assign each gene the stage its expression is highest in. DERIVED, never evidence.
Every contributing column is z-scored first, because they are not on one scale — FPKM, iTRAQ ratios and log intensities cannot be compared as raw numbers, and whichever column happened to have the largest units would otherwise win every gene.
A gene is left unlabeled unless one stage leads the next by MIN_MARGIN. Assigning every gene a
class would manufacture confident labels for the flat majority, and a label that is really a coin
toss is worse than an absent one: it looks like a measurement in every table it appears in.
Read the class counts with one caveat in mind. Tachyzoite and bradyzoite expression correlate at r = 0.89 while sporulated oocyst correlates with both at ~0.30, so a gene high in tachyzoite is usually also high in bradyzoite and neither wins by a margin, whereas oocyst wins easily. The result is 1,380 oocyst calls against 230 tachyzoite -- which reflects how separable the stages are from each other, not how many genes each stage uses. The margin rule is doing its job here; it is the interpretation that has to stay careful.
Attach the measured cell-cycle columns and the derived stage column to the node table.