Low priority — two small follow-ups from #43, plus one upstream watch.
1. Seed a level's vocabulary from Azimuth (cta markers assemble --ref-label-csv)
cta markers assemble can already seed markers_<level>.json from any labelled reference via
from_reference() (it runs rank_genes_groups over an obs column). Azimuth's per-cell labels
make the query itself such a reference — azimuth_medium's 85 pan-body classes are a
plausible L2 prior for a broad or multi-tissue human query, and they arrive with a CL crosswalk.
Today that takes three manual steps. Making it one needs roughly 15 lines:
- add
--percell-out PATH to cta crosscheck azimuth (~5 lines) so the per-cell labels are
written, not just the per-cluster aggregate
- add
--ref-label-csv PATH to assemble_markers.py: read the CSV, join on obs_names, then
fall through to the existing from_reference path
The output is a prior to curate, exactly like the CellTypist source — assemble_markers.py
already says so in its docstring, and that applies here unchanged. Worth doing only if L2
hierarchy drafting turns out to be a bottleneck in practice.
2. Remove the "False" workaround if upstream fixes it
src/cta/run_azimuth.py works around
satijalab/panhumanpy#47: panhumanpy writes
the literal string "False" into azimuth_broad/medium/fine for cells whose 8 hierarchical
heads do not agree on a self-consistent path. We substitute final_level_labels for those cells
and report the rate as frac_inconsistent_hierarchy — which is useful on its own as an
out-of-distribution alarm, so only the substitution would go away, not the metric.
The issue is open with no maintainer response. If they introduce a proper sentinel (None/NaN)
or a documented fallback, revisit _resolve in run_azimuth.py.
3. CL-id cross-validation at write-back — decided AGAINST for now
Recorded so it isn't re-proposed without new evidence. cta crosscheck azimuth writes
azimuth_cl_<level>.csv, an independent label → CL:ID assertion, and it is tempting to have
cta report write-back warn when it disagrees with the cl_id Claude assigned.
Not worth building yet: Claude's labels and Azimuth's come from different vocabularies, so a
mismatch is the expected case, not the exception — a warning would fire on most rows and erode
a gate that currently has a clean signal-to-noise ratio. Only a minority of the shipped crosswalk
rows are skos:exactMatch; restricting to those is what would make it viable at all.
Low priority — two small follow-ups from #43, plus one upstream watch.
1. Seed a level's vocabulary from Azimuth (
cta markers assemble --ref-label-csv)cta markers assemblecan already seedmarkers_<level>.jsonfrom any labelled reference viafrom_reference()(it runsrank_genes_groupsover an obs column). Azimuth's per-cell labelsmake the query itself such a reference —
azimuth_medium's 85 pan-body classes are aplausible L2 prior for a broad or multi-tissue human query, and they arrive with a CL crosswalk.
Today that takes three manual steps. Making it one needs roughly 15 lines:
--percell-out PATHtocta crosscheck azimuth(~5 lines) so the per-cell labels arewritten, not just the per-cluster aggregate
--ref-label-csv PATHtoassemble_markers.py: read the CSV, join onobs_names, thenfall through to the existing
from_referencepathThe output is a prior to curate, exactly like the CellTypist source —
assemble_markers.pyalready says so in its docstring, and that applies here unchanged. Worth doing only if L2
hierarchy drafting turns out to be a bottleneck in practice.
2. Remove the
"False"workaround if upstream fixes itsrc/cta/run_azimuth.pyworks aroundsatijalab/panhumanpy#47: panhumanpy writes
the literal string
"False"intoazimuth_broad/medium/finefor cells whose 8 hierarchicalheads do not agree on a self-consistent path. We substitute
final_level_labelsfor those cellsand report the rate as
frac_inconsistent_hierarchy— which is useful on its own as anout-of-distribution alarm, so only the substitution would go away, not the metric.
The issue is open with no maintainer response. If they introduce a proper sentinel (
None/NaN)or a documented fallback, revisit
_resolveinrun_azimuth.py.3. CL-id cross-validation at write-back — decided AGAINST for now
Recorded so it isn't re-proposed without new evidence.
cta crosscheck azimuthwritesazimuth_cl_<level>.csv, an independentlabel → CL:IDassertion, and it is tempting to havecta report write-backwarn when it disagrees with thecl_idClaude assigned.Not worth building yet: Claude's labels and Azimuth's come from different vocabularies, so a
mismatch is the expected case, not the exception — a warning would fire on most rows and erode
a gate that currently has a clean signal-to-noise ratio. Only a minority of the shipped crosswalk
rows are
skos:exactMatch; restricting to those is what would make it viable at all.