Skip to content

aedes_add_neurons enrichment + aedes_set_meta / aedes_set_group - #10

Open
jefferis wants to merge 6 commits into
mainfrom
feature/aedes-set-group
Open

aedes_add_neurons enrichment + aedes_set_meta / aedes_set_group#10
jefferis wants to merge 6 commits into
mainfrom
feature/aedes-set-group

Conversation

@jefferis

@jefferis jefferis commented Aug 4, 2026

Copy link
Copy Markdown
Member

Summary

  • aedes_add_neurons now auto-fills soma_xyz, nucleus_id, side and point_xyz (never overwriting non-NA values on existing rows), validates status against a live aedes_main vocabulary, and requires superclass / status / initials by default (via required=). Initials default to getOption("aedes.initials").
  • The update-existing engine is refactored out as .aedes_update_existing and shared with two new helpers:
    • aedes_set_meta() — bulk update columns on existing aedes_main rows.
    • aedes_set_group() — convenient grouping / add-to-group on aedes_main.

Test plan

  • devtools::check() clean on macOS
  • aedes_add_neurons(ids, superclass=..., status=..., cell_class=...) on a known KC + a not-yet-added id: verify soma_xyz, nucleus_id, side and point_xyz are populated for the new row; existing row's non-NA cells are preserved
  • status = "not_a_status" errors with the live vocabulary listed
  • Missing superclass / initials errors with the pointer to options(aedes.initials=...)
  • aedes_set_meta() updates the intended cells and leaves others alone
  • aedes_set_group() creates a new group and appends to an existing one as expected

🤖 Generated with Claude Code

…equire curation fields

Auto-fills soma_xyz + nucleus_id (via aedes_soma_position) and side (via
aedes_point_side on the soma nm coords, falling back to aedes_key_point
with a warning when the soma cascade returns nothing). Callers' `...`
values always win, and existing non-NA cells on update rows are never
clobbered.

Also introduces:
  - `status` shortlist in signature (tab-completion); values outside the
    shortlist are live-checked against unique(aedes_main$status) and
    rejected with a helpful message.
  - `required = c("superclass","status","initials")` — missing fields
    error, pointing users at options(aedes.initials="XY").
Factor the timestamp-pinned "update existing aedes_main rows by root_id"
core out of aedes_add_neurons into internal helpers in flytable.R:

- .aedes_pin_meta(): pin one timestamp, return latest ids + a
  timestamp-consistent aedes_main (shared read).
- .aedes_update_existing(): resolve root_id -> _id in that snapshot and
  write exactly the supplied columns (verbatim; no no-clobber). Update-only
  -- absent ids are returned in `missing` rather than appended. Errors on
  duplicated root_id; accepts a pre-pinned am/ts to avoid a second read.
- .aedes_reject_dry_run(): guard for `...`-carrying entry points so a
  mistyped `dry_run` errors clearly instead of being written as a column.

aedes_add_neurons now pins via .aedes_pin_meta and routes its update branch
through .aedes_update_existing, keeping its auto-col no-clobber policy local
and its append logic and list(up, new) return shape unchanged. Verified the
dry-run update frame is identical() to the pre-refactor version.
Port aedes_set_meta into the package (previously a project-local helper).
Bulk-updates existing rows from a per-row data.frame of metadata, resolving
ids via aedes_ids() and writing through the shared .aedes_update_existing()
engine so the join is timestamp-consistent.

Update-only: rows with status bad_nucleus/duplicate/not_a_neuron are dropped
first, and any remaining id absent from aedes_main is an error (all-or-nothing,
nothing is written). Uses the standard `dryrun` argument with the alias guard.
New aedes_set_group() assigns a shared `group` id to a set of neurons,
building on aedes_set_meta()'s update engine (writing directly to it, reusing
the pinned snapshot so the returned preview matches what is written).

Improvements over the old project-local helper:
- `group=` now works: integer forces an id; 0/NA ungroups; a query/ids joins
  the group of those neurons (join-by-example).
- join_existing controls conflicts when selected neurons are already grouped:
  NA (default) refuses to guess -- warns on dry run, errors on a live write,
  and prints the exact re-run call; TRUE joins the existing group (keeping its
  id, merging several with a warning); FALSE mints a fresh group from
  min(serial_id).
- Warns when a reassignment would split an existing group (orphan guard).
- Dry run returns a per-neuron preview (root_id, serial_id, group_old,
  group_new, changed) instead of a bare number; live writes only changed rows.

Both aedes_set_meta and aedes_set_group added to the _pkgdown reference index.
Exposes fafbseg::cam_meta()'s new translate_ids argument through aedes_meta
(and thus aedes_ids). The stale-id translation itself now lives in cam_meta,
so aedes_meta simply forwards the argument rather than reimplementing the
flywire_latestid() step locally (removing the .aedes_explicit_ids helper).
…ect support

Add generic multi-select column merge across the three writers so curator
initials land in the aedes_main annotator/proofreader columns without
overwriting existing tokens.

- .aedes_append_multiselect(): shared engine that merges a named list of
  values into the update frame, per column, sorted-unique. Comma-string
  output (fafbseg's flytable_listify_multiselect_col handles the JSON).
  wipe = FALSE (default) appends; wipe = TRUE replaces.
- .aedes_resolve_initials(): shared TRUE/FALSE/vector -> tokens resolver
  that looks up getOption("aedes.initials") when TRUE.
- Wire annotator = TRUE, proofreader = FALSE, wipe = FALSE through
  aedes_add_neurons(), aedes_set_meta(), aedes_set_group().
- Empty-cell handling: drop actual NA and empty/whitespace tokens only;
  literal "NA" / "NaN" strings are treated as data so real curator
  initials survive round-trips.
- aedes_add_neurons(): improved missing-required-columns error message
  pointing at options(aedes.initials = "XY") for initials specifically.
- aedes-package.R: document aedes.version and aedes.initials options.
@jefferis
jefferis force-pushed the feature/aedes-set-group branch from 5796b60 to 647432b Compare August 17, 2026 14:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant