vignettes/match_em_to_line.Rmd
match_em_to_line.RmdFind the FlyWire-FAFB-v783 cell matched by a published, weakly-labelling split-GAL4 — the kind of cell where the line says “this is the neuron” but the LM stack alone is not specific enough to be sure.
The example here is SS32423 (Sterne et al. 2021,
aMulet), reported to label an Allatostatin-A
(AstA) neuron of the subesophageal zone (SEZ). Both of its
hemidrivers — AD VT019900 and DBD R65D06 — lie
in the AstA locus on 3R. The canonical “AstA-GAL4” tile
R65D05 (Hergarden et al. 2012) is the chromosomal neighbour
of R65D06, and together with R65D07 and a few
flanking tiles forms a natural panel of AstA-locus
drivers. The FAFB-v783 cell that matches every panel member is
the strong candidate.
The pipeline chains four filters to a short ranked list:
v3_9_0);soma_dcv_density — the
dense-core-vesicle proxy for peptidergic identity, consistent with AstA
secretion;Outputs: a ranked CSV (in inst/extdata/asta_sez/) and a
side-by-side figure of the SS32423 MIP and the surviving candidate(s). A
reproducer sits at inst/scripts/run_asta_sez.R.
if (!require("remotes")) install.packages("remotes")
remotes::install_github("natverse/neuronbridger")
remotes::install_github("natverse/fafbseg")
remotes::install_github("natverse/nat.flybrains")
remotes::install_github("natverse/nat.templatebrains")
remotes::install_github("natverse/nat.jrcbrains")
install.packages(c("arrow", "dplyr", "tidyr", "ggplot2", "ggrepel"))
library(neuronbridger)
library(arrow); library(dplyr); library(tidyr); library(ggplot2)
NB_VERSION <- "v3_9_0" # current release; ships FlyWire-FAFB-v783 MIPsThe compiled FAFB-v783 metadata + soma-DCV-detection feather tables
used here are an in-prep product of the Wei-Chung Allen Lee lab (Harvard
/ lee-lab DCV manuscript, in preparation). Replace DCV_DIR
with the directory holding the equivalent feathers on your own machine —
the rest of the pipeline is path-agnostic.
The panel is built by hand from the literature: SS32423 plus the GMR
and VT enhancer fragments that tile the AstA locus and have FlyLight
imaging in NeuronBridge. R65D04 is included in the
literature but absent from NB v3_9_0 — confirm and drop it on the
fly.
driver_panel <- tibble::tribble(
~line, ~role,
"SS32423", "primary lead — aMulet split (Sterne et al. 2021); both halves AstA-locus",
"R65D05", "Pfeiffer 'AstA-GAL4' (Hergarden 2012; Pool 2014; Landayan 2021)",
"R65D06", "DBD half of SS32423 — Pfeiffer tile in AstA locus",
"R65D04", "neighbouring AstA-locus tile — absent from NB v3_9_0",
"R65D07", "neighbouring AstA-locus tile",
"R65E01", "neighbouring AstA-locus tile",
"VT019900", "AD half of SS32423 — Vienna Tile in AstA locus"
)Confirm and select brain MIPs (FAFB hits only come from brain MIPs,
not VNC ones). NB stores many redundant MIPs per line — broad lines have
50+ — and neuronbridge_hits() calls
plyr::rbind.fill() internally which is quadratic in the
number of result rows, so we cap at 5 MIPs per line. Multiple MIPs of
the same line are slightly different stainings of the same GAL4, and
slice_max() downstream takes the best score per neuron, so
5 is plenty.
panel_info <- list()
for (ln in driver_panel$line) {
out <- try(neuronbridge_info(ln, dataset = "by_line",
version = NB_VERSION), silent = TRUE)
if (inherits(out, "try-error") || !nrow(out)) next
brain <- out[out$anatomicalArea == "Brain", , drop = FALSE]
if (!nrow(brain)) next
brain <- head(brain, 10)
brain$line <- ln
panel_info[[ln]] <- brain
}
panel_info <- bind_rows(panel_info)
# In v3_9_0: SS32423 (16 brain MIPs), R65D05 (75), R65D06 (60), R65D07
# (15), R65E01 (48), VT019900 (21); R65D04 absent. Capped at 10 → 60
# MIPs total.SS32423 ships 16 brain MIPs in v3_9_0. The dominant
pattern is a bilateral SEZ-soma pair with arbours ascending
dorso-medially — the cell the line was designed to label. A few MIPs are
MCFO stochastic single-cell renders, so inspect the full set before
choosing a representative MIP:

For each driver, fetch its colour-depth hits, restrict to
FlyWire-FAFB (libraryName == "FlyWire_FAFB_v783_realign"),
and cache per line.
KEEP_COLS <- c("publishedName","libraryName","normalizedScore",
"matchingPixels","alignmentSpace","anatomicalArea","gender")
hits_list <- list()
for (ln in unique(panel_info$line)) {
ln_mips <- panel_info[panel_info$line == ln, ]
rows <- list()
for (i in seq_len(nrow(ln_mips))) {
h <- try(neuronbridge_hits(ln_mips$nb.id[i], version = NB_VERSION),
silent = TRUE)
if (inherits(h, "try-error") || is.null(h) || !nrow(h)) next
h <- h[grepl("FlyWire", h$libraryName), , drop = FALSE]
if (!nrow(h)) next
h <- as.data.frame(h[, intersect(KEEP_COLS, colnames(h)), drop = FALSE])
h$normalizedScore <- as.numeric(h$normalizedScore)
h$query_line <- ln
h$query_mip <- ln_mips$nb.id[i]
rows[[length(rows)+1L]] <- h
}
hits_list[[ln]] <- if (length(rows)) bind_rows(rows) else tibble()
}
hits_raw <- bind_rows(hits_list)
hits_raw$root_783 <- sub("^flywire_fafb:v783:", "", hits_raw$publishedName)
# Live numbers (cap=10 MIPs/line):
# SS32423 6148 hits R65D05 9845 R65D06 14314
# R65D07 10515 R65E01 8807 VT019900 10038
# total: 59667 FlyWire hit-rows across the panel.
hits_best <- hits_raw |>
group_by(query_line, root_783) |>
slice_max(normalizedScore, n = 1, with_ties = FALSE) |>
ungroup()Per-line top-N with the elbow cutoff helper (drop candidate
k if score < 75% of k-1 or < 20% of top score;
cap at 25). Reused from
abdominal_peripheral_targets.Rmd.
top_with_elbow <- function(df, cap = 25,
drop_frac = 0.75,
floor_frac = 0.20) {
df <- df[order(df$normalizedScore, decreasing = TRUE), , drop = FALSE]
if (!nrow(df)) return(df)
keep <- TRUE
if (nrow(df) > 1) {
ratios <- df$normalizedScore[-1] / df$normalizedScore[-nrow(df)]
keep <- c(TRUE,
cumprod(ratios >= drop_frac) == 1 &
df$normalizedScore[-1] / df$normalizedScore[1] >= floor_frac)
}
head(df[keep, , drop = FALSE], cap)
}
hits_top <- hits_best |>
group_by(query_line) |>
group_modify(~ top_with_elbow(.x, cap = 25)) |>
ungroup()
# 150 line-neuron pairs across 148 unique candidate FlyWire neurons.The soma-DCV feather classifies each vesicle by neuropil. Three
practical points: regions can be comma-joined on neuropil boundaries
("AL_R,GNG,SAD"); outside_<NEUROPIL>
tags mark the cortex rind where somas actually sit (so a strict
neuropil == "GNG" filter would drop most genuine GNG-soma
neurons); and ~⅓ of FAFB-v783 neurons have no soma DCVs at all
(ascending cells with VNC somas). We tokenise on commas, accept inner
SEZ neuropils plus their outside_* rinds, score by
fraction of soma-DCVs hitting any SEZ token, and keep
borderline / unknown cases rather than silently dropping them. The
distribution is bimodal so a 0.5 threshold is safe and 0.1 is a generous
safety net.
# Periesophageal SEZ — the broad Ito-2014 definition. The narrow
# 6-neuropil set (GNG / SAD / AMMC / FLA only) misses cells like
# CB0108 whose soma rind is `outside_IPS_L` but whose hemilineage
# (LB19) is canonically SEZ. Add PRW, IPS, SPS, VES, WED.
SEZ_INNER <- c("GNG","SAD","AMMC_L","AMMC_R","FLA_L","FLA_R",
"PRW","IPS_L","IPS_R","SPS_L","SPS_R",
"VES_L","WED_L","WED_R")
SEZ_TOK <- c(SEZ_INNER, paste0("outside_", SEZ_INNER))
soma_dcv <- read_feather(SOMA_DCV_FEATHER,
col_select = c("root_783", "neuropil"))
sez_tok <- function(np, set) {
vapply(strsplit(np, ",", fixed = TRUE),
function(x) any(x %in% set), logical(1))
}
soma_dcv <- soma_dcv |>
mutate(any_sez = sez_tok(neuropil, SEZ_TOK),
inner_sez = sez_tok(neuropil, SEZ_INNER))
soma_class <- soma_dcv |>
group_by(root_783) |>
summarise(n_dcv = n(),
frac_sez = mean(any_sez),
frac_sez_inner = mean(inner_sez),
top_token = names(sort(table(neuropil), decreasing = TRUE))[1],
.groups = "drop") |>
mutate(soma_zone = case_when(
frac_sez >= 0.5 ~ "SEZ",
frac_sez >= 0.1 ~ "SEZ_borderline",
TRUE ~ "non_SEZ"
))
table(soma_class$soma_zone)
# Live: SEZ ~3960 borderline ~250 non_SEZ ~103,000.The soma_dcv_density column on the meta is the canonical
metric (DCV voxels / soma voxels). Threshold over central-brain neurons
only — the optic-lobe DCV distribution is its own thing and would
otherwise drag the percentile downwards.
meta <- read_feather(META_FEATHER) |>
mutate(root_783 = as.character(fafb_783_id))
cb <- meta |> filter(region == "central_brain", !is.na(soma_dcv_density))
dcv_thr <- quantile(cb$soma_dcv_density, probs = 0.90, na.rm = TRUE)
ecdf_cb <- ecdf(cb$soma_dcv_density)
meta <- meta |> mutate(dcv_pct = ecdf_cb(soma_dcv_density),
dcv_rich = soma_dcv_density >= dcv_thr)Score per neuron, then sort. The hard requirement is
in_ss32423 plus soma-zone-OK; everything else (consensus,
DCV-rich, R65D05 membership) is a nudge added to
rank_score.
cand <- hits_top |>
left_join(soma_class, by = "root_783") |>
left_join(meta |> select(root_783, cell_class, cell_type, super_class,
hemilineage, side, neurotransmitter_predicted,
neuropeptide_verified,
soma_dcv_density, dcv_pct, dcv_rich),
by = "root_783")
ranked <- cand |>
mutate(in_ss32423 = query_line == "SS32423",
in_R65D05 = query_line == "R65D05") |>
group_by(root_783) |>
summarise(
n_lines = n_distinct(query_line),
in_ss32423 = any(in_ss32423),
in_R65D05 = any(in_R65D05),
lines = paste(sort(unique(query_line)), collapse = ","),
best_score = max(normalizedScore, na.rm = TRUE),
score_sum = sum(pmin(normalizedScore, 50000), na.rm = TRUE),
soma_zone = soma_zone[1], frac_sez = frac_sez[1],
cell_type = cell_type[1], hemilineage = hemilineage[1],
super_class = super_class[1], nt = neurotransmitter_predicted[1],
np_verified = neuropeptide_verified[1],
soma_dcv_density = soma_dcv_density[1],
dcv_pct = dcv_pct[1], dcv_rich = dcv_rich[1],
.groups = "drop"
) |>
mutate(soma_zone = ifelse(is.na(soma_zone), "unknown", soma_zone),
dcv_rich = ifelse(is.na(dcv_rich), FALSE, dcv_rich),
sez_ok = soma_zone %in% c("SEZ","SEZ_borderline","unknown"),
rank_score = (n_lines * 1.0)
+ (best_score / 50000)
+ ifelse(in_ss32423, 0.5, 0)
+ ifelse(dcv_rich, 0.5, 0)
+ ifelse(in_R65D05, 0.5, 0)) |>
filter(sez_ok) |>
arrange(desc(in_ss32423), desc(n_lines), desc(rank_score))If after all the joins and filters none of SS32423’s NB hits survived, the pipeline has a bug. Always print this before trusting the cross-line consensus.
ss <- ranked |> filter(in_ss32423)
cat(sprintf("SS32423 candidates retained: %d\n", nrow(ss)))
cat(sprintf(" ... SEZ-soma %d borderline %d unknown %d non_SEZ %d\n",
sum(ss$soma_zone == "SEZ"),
sum(ss$soma_zone == "SEZ_borderline"),
sum(ss$soma_zone == "unknown"),
sum(ss$soma_zone == "non_SEZ")))
cat(sprintf(" ... DCV-rich (>=p90): %d\n", sum(ss$dcv_rich, na.rm = TRUE)))
stopifnot("Pipeline lost all SS32423 hits — soma_zone filter probably too tight." = nrow(ss) > 0)
# Live: 22 SS32423 candidates retained — 18 SEZ, 0 borderline, 4 unknown.The 9 SEZ-soma SS32423 candidates from the live run (cap=10 MIPs/line). The SS32423-membership column is sorted to the top, then number of consensus lines, then the rank score:
# Top SS32423 ∩ SEZ-soma candidates (cap=10):
cell_type hemilineage super_class n_lines lines best_score dcv_pct dcv_rich np
1 CB0602 putative_primary central_brain_intrinsic 2 R65D05,SS32423 42344 0.866 FALSE -
2 CB0239 LB11 central_brain_intrinsic 2 SS32423,VT019900 41537 0.402 FALSE -
3 DNg22 putative_primary descending 1 SS32423 37532 1.000 TRUE FMRFa
4 CB0456 putative_primary central_brain_intrinsic 1 SS32423 44783 0.839 FALSE -
5 CB0544 putative_primary central_brain_intrinsic 1 SS32423 39122 0.296 FALSE -
6 DNge046 LB5__prim descending 1 SS32423 36493 0.437 FALSE -
7 CB1475 LB23 central_brain_intrinsic 1 SS32423 35328 0.648 FALSE -
8 CB3901 MX0__prim central_brain_intrinsic 1 SS32423 33566 0.753 FALSE -
9 CB3902 LB0_anterior central_brain_intrinsic 1 SS32423 33229 0.487 FALSE -
A further 16 SS32423 hits have non-SEZ somas (e.g. soma in SMP / LH / SLP cortex rind) and are kept in the full ranked CSV but excluded from the SEZ-OK figures. These are real SS32423 hits but a poor fit for “soma in the SEZ” — typically off-target labelling of the line.
Two graphical summaries — first the dot plot of best NB score versus consensus, second the ranked bar with DCV-rich highlight:


The driver-panel hit matrix shows which of our six AstA-locus drivers hit each top-25 candidate — useful for seeing at a glance who’s a consensus winner and who’s a one-line hit:

A few things stand out:
CB0602 is the only neuron hit by both SS32423
and R65D05 (the canonical AstA-GAL4) at high score. It’s a
central_brain_intrinsic cell with soma in the SEZ
(frac_sez = 1.0), putative_primary
hemilineage, predicted ACh, and dcv_pct = 0.866 (just below
the strict p90 DCV-rich threshold). FlyWire root
720575940632295751 (left side).CB0108 (LB19) is hit by SS32423 alone
but is massively DCV-rich
(soma_dcv_density = 16.4, dcv_pct ≈ 0.99); its
soma sits at the dorsal outside_IPS_L rind. With the broad
peri-esophageal SEZ definition (above) it classifies as SEZ. FlyWire
root 720575940620093019 (right side).inst/extdata/asta_sez/cache/hits_*.rds for the unfiltered
hits. See Step 7b below.CB0239 (LB11 hemilineage,
ACh, dcv_pct = 0.402) is hit by both SS32423 and
VT019900 (SS32423’s AD half). Lower DCV signal, but
LB11 is an SEZ-relevant lineage. Worth visually verifying.
FlyWire root 720575940634548194.DNg22 turns up in SS32423 alone —
confirmed np_verified = "FMRFa", very DCV-rich
(dcv_pct = 1.0, soma_dcv_density = 50.1). This
is a known peptidergic descending neuron rather than the canonical
Hergarden-type SEZ AstA cell, but the SS32423 colour-MIP almost
certainly contains the DNg22 dendritic arbour and that’s why it ranks.
Treat as a secondary hit, not the target.LB23, CB3901 in
MX0__prim, CB3902 in LB0_anterior, CB0456 /
CB0544 in putative_primary) sit in the next rank tier.
These are all SEZ-soma cells with various NTs and mid-range DCV
percentiles — worth a 3-D look for any morphology match.Hergarden, Tayler & Anderson (2012; PMC3309792) describe roughly four AstA-positive neurons clustered around the SEZ — two bilateral pairs. Our SS32423 hits map to this directly:
putative_primary lineage, ACh):
720575940632295751 (top hit, SS32423 ∩
R65D05)720575940640469848 (in SS32423 + R65D05 +
R65D06 raw caches; falls below the per-line elbow cap)LB19
lineage, ACh):
720575940620093019 (top non-SEZ-strict hit,
dcv_pct 0.99)720575940624028855 (in SS32423 + R65D06 raw
caches)Render all four meshes
(inst/scripts/asta_sez_4cell.R):

The bilateral symmetry is unambiguous and the dorsal-ventral split matches the figures in Hergarden 2012. CB0602 + CB0108 together = the 4 SEZ-AstA cells that motivated SS32423 in the first place.
Of course, none of this is news to the FlyWire community: these large projection neurons are already annotated as the AstA1 cell type in codex. The point of the pipeline above isn’t to discover AstA1 from scratch, but to show that SS32423 + AstA-locus driver consensus + DCV-density soma scoring converges on AstA1 without using the AstA1 annotation as input — the same recipe should generalise to other peptidergic populations that don’t yet have a canonical FlyWire label.
The 16 SS32423 hits with non-SEZ somas (visible in
asta_sez_ranked_full.csv) belong to a different cluster —
see Step 10 below.
The ranked CSV with all 100+ candidates and full annotations is in
inst/extdata/asta_sez/asta_sez_ranked_full.csv. The top-30
cut is asta_sez_ranked_top30.csv.
nat.ggplot
nat.ggplot::geom_neuron() plots a neuron /
neuronlist / mesh as a 2-D ggplot — the same idiom the
lee-lab DCV repo uses for its FAFB figures
(R/visualise/fafb_flange.R,
fig_2_dcv_predictions_fafb.Rmd).
We fetch the FlyWire meshes for the top 2 candidates
(~22 MB each, ~10 s/neuron from CloudVolume) and project their vertices
to 2-D as a low-alpha point cloud — that produces a denser, MIP-like
volumetric render than the L2 skeleton paths. The FAFB14 brain and SEZ
neuropil meshes from elmr provide context.
library(nat); library(nat.ggplot); library(elmr); library(fafbseg)
library(ggplot2); library(patchwork)
options(fafbseg.flywire_dataset = "flywire_fafb_public")
CB0602 <- "720575940632295751"
CB0239 <- "720575940634548194"
m <- fafbseg::read_cloudvolume_meshes(c(CB0602, CB0239))
brain <- elmr::FAFB14.surf
sez_surf <- subset(elmr::FAFB14NP.surf,
c("GNG","SAD","FLA_R","FLA_L","AMMC_R","AMMC_L"))
# Project mesh vertices to 2-D as a low-alpha point cloud — this is
# what produces the volumetric "MIP-like" arbour density.
mesh_xy <- function(mesh) {
v <- nat::xyzmatrix(mesh)
data.frame(X = v[,1], Y = v[,2], Z = v[,3])
}
mk_panel <- function(mesh, title, neuron_col) {
ggplot() +
geom_neuron(brain, cols = "grey75", alpha = 0.30) +
geom_neuron(sez_surf, cols = "#3182bd", alpha = 0.40) +
geom_point(data = mesh_xy(mesh), aes(x = X, y = Y),
colour = neuron_col, alpha = 0.04, size = 0.15) +
coord_fixed() + scale_y_reverse() +
labs(title = title) +
theme_void(base_size = 11) +
theme(plot.title = element_text(hjust = 0.5))
}
(mk_panel(m[[CB0602]], "CB0602 — SS32423 ∩ R65D05", "magenta") |
mk_panel(m[[CB0239]], "CB0239 — SS32423 ∩ VT019900", "darkorange"))The result
(inst/images/asta_sez_candidates_natggplot.png):

CB0602 has the soma in the SEZ neuropil (left side) and arbours extending dorso-medially into central brain — exactly the bilateral SEZ-soma → SMP-arbour pattern visible across the SS32423 montage. CB0239 is a tighter, more SEZ-local cell.
Stack the SS32423 NB brain MIP next to depth-encoded renders of the two SEZ AstA cell types — CB0602 (ventral SEZ pair) and CB0108 (dorsal/IPS pair) — using the same blue→cyan→green→yellow→orange→red→magenta ramp NeuronBridge uses, so the three panels read consistently:

The reproducer for this figure (and the geom_neuron
panel above) is inst/scripts/asta_sez_meshes.R — fetches
the FlyWire meshes once (~10 s/neuron, ~22 MB each, cached to
inst/extdata/asta_sez/cache/meshes_*.rds) and renders both
the 2-panel geom_neuron figure and this 3-row depth-encoded
panel.
For a true NeuronBridge-style colour-depth MIP from a
FlyWire mesh (i.e. the Janelia ColorMIP algorithm applied to a
re-rendered NRRD in the NeuronBridge-compatible
JRC2018U_HR grid: 1210 × 566 × 174 at 0.519 × 0.519 ×
1.0 µm), nrrd_to_mip_direct() does the whole thing in pure
R — no FIJI launch required:
sez_hits <- c(CB0602 = "720575940632295751", # ventral SEZ pair
CB0108 = "720575940620093019") # dorsal IPS pair
savefolder <- "~/asta_sez_mips"
# 1) Render each FlyWire mesh into a JRC2018U_HR-sized NRRD
for (id in sez_hits) {
root_id_to_nrrd(id,
reference = "JRC2018U_HR",
savefolder = savefolder)
}
# 2) Colour-depth MIP every NRRD in the folder, in pure R
nrrd_to_mip_direct(savefolder, target_space = "brain", format = "png")
# Output: <savefolder>/color_mips/*_colormip.pngThe colormip_direct_vs_fiji vignette walks through the
algorithm, contrasts nrrd_to_mip_direct() against the
FIJI-launching nrrd_to_mip(), and validates byte-for-byte
against Jasper Phelps’s Python port in the BANC connectome package.
Inspecting the SS32423 montage (Step 1) more carefully, row 1
columns 2–4 show clear bright cells outside the SEZ —
in the upper-medial brain. Hentze et al. 2015 mapped AstA expression to
several non-SEZ groups (median protocerebrum / pars intercerebralis,
pars lateralis, optic lobe), so we should expect SS32423 to label some
of those too even if the canonical AstA-GAL4 (R65D05)
doesn’t.
Pulling the 16 SS32423 hits with non-SEZ somas from
asta_sez_ranked_full.csv confirms the pattern: they cluster
overwhelmingly in the SMP / SLP with several bilateral
cell-type recurrences (strong evidence these are real, consistent
SS32423 targets rather than colour-MIP noise):
| cell_type | hemilineage | NT | DCV pct | recurrence |
|---|---|---|---|---|
SMP202 |
putative_primary |
ACh | 0.95–0.97 | bilateral pair |
SMP540 |
SMPpd2 |
glutamate | 0.87–0.92 | bilateral pair (×3 hits) |
CB2082 |
SMPp&v1_posterior |
glutamate | 0.86–0.93 | bilateral pair |
CL176 |
SMPp&v1_posterior |
glutamate | 0.80–0.88 | bilateral pair |
(CB0108 initially appeared here too because the strict
tokeniser classified its outside_IPS_L soma rind as
non-SEZ, but biologically it belongs to the SEZ AstA group — see Step 7b
— and we’ve moved it back there.)
Render the strongest non-SEZ candidates with the same mesh-vertex
point-cloud pipeline (see inst/scripts/asta_sez_meshes.R
for the mk_panel() definition):
others <- c(
SMP202_R = "720575940626412563",
SMP202_L = "720575940628248326",
SMP540_R = "720575940623972792",
SMP540_L = "720575940616330011",
CB2082_R = "720575940623952679"
)
m_other <- fafbseg::read_cloudvolume_meshes(unname(others))
# ...same mk_panel() as in step 8...
The figure makes two things clear:
SMP202 (bilateral, ACh) has somas in
the upper-medial brain (SMP cortex rind) and dense bilateral arbours
fanning across SMP / SLP — the exact cell pattern visible in
row 1 cols 2–4 of the SS32423 montage.SMP540 (bilateral, glutamate) is a
tighter dorsal-medial cell in the SMPpd2 hemilineage —
co-labels in the same SS32423 pattern, alongside SMP202.None of these non-SEZ candidates are hit by
R65D05 (the canonical Hergarden AstA-GAL4 — see
the heatmap in step 7). That means we cannot assert from this analysis
alone that they are AstA-positive; only that they are consistent SS32423
targets which happen to be DCV-rich (hence likely peptidergic). The
interpretation is one of:
R65D05
simply doesn’t capture them because that Pfeiffer fragment is a
sub-region of AstA flanking sequence selected to label SEZ-AstA cells.
Other AstA reporters (the Hentze 2015 P{AstA-GAL4.2.1},
CRISPR AstA[SK1], MiMIC T2A-GAL4) would be the test — none
are in NB, so this requires direct immunostaining or LM imagery from
those lines.VT019900, R65D06) drive in the
SMP independently of AstA expression, and the split happens to intersect
them. Bilateral cell-type recurrence makes this less likely (random
off-target hits don’t usually mirror left↔︎right) but it’s still on the
table.The next step in either direction is to render these candidates as proper colour-depth MIPs against the SS32423 NB MIPs from row 1 cols 2–4 of the montage and judge visual agreement.
dcv_pct = 0.866 is
consistent with peptide release but does not pin down which
neuropeptide. The np_verified column will catch
AstA-positive neurons that have already been annotated; absence there is
“not yet verified”, not “negative”.outside_* rind classes are both included on purpose, and
unknown (no soma DCVs) is kept rather than
dropped. The hard filter is in_ss32423 plus cross-line
consensus; soma-zone is a nudge.n_lines >= 2). If you need that,
raise the cap in step 1 and tolerate a longer pipeline run; the
inst/extdata/asta_sez/cache/ per-line .rds
files mean a re-run only does the new lines.v3_9_0, the first release with the corrected
FlyWire-v783 alignment. Earlier releases will give worse top-N hit
lists.P{AstA-GAL4.2.1} (Hentze 2015), AstA[SK1]
CRISPR, MiMIC T2A-GAL4 — all not in NB and so cannot contribute to the
consensus here.R65D05 (the canonical AstA-GAL4) hits it,
not just whether SS32423’s halves do. By that test, CB0602
wins.