Read a Cellucid history: trackers, branches, groups, steps, notes, turns
cellucid_trackers.RdThe reading model of a Cellucid history, function for function
cellucid-python's cellucid.history: every record is the history
model's (inst/history_model.schema.json), its fields named in snake
case. Both packages are held to the same shared golden history and the same
expected reading.
Usage
cellucid_trackers(session)
cellucid_tracker(session, tracker = NULL)
cellucid_branches(tracker)
cellucid_branch(tracker, branch = NULL)
cellucid_groups(tracker)
cellucid_group(tracker, group)
cellucid_steps(tracker, branch = NULL)
cellucid_step(tracker, step)
cellucid_step_state(tracker, step)
cellucid_step_diff(tracker, a, b, other = NULL)
cellucid_stale(tracker)
cellucid_notes(tracker)
cellucid_turns(tracker)
cellucid_journal(tracker)
cellucid_methods(tracker, branch = NULL)
cellucid_pseudocode(tracker, branch = NULL)Arguments
- session
What
cellucid_read_session()orcellucid_session_result()returned.- tracker
For
cellucid_tracker(): a tracker's name (as the web app compares names: white space collapsed, case ignored; among the trackers not removed) or id,NULLfor the active one. Elsewhere: whatcellucid_tracker()returned.- branch
A branch's name or id;
NULLfor the active branch (cellucid_branch()), every step (cellucid_steps()) or the main branch (cellucid_methods(),cellucid_pseudocode()).- group
A group's name (compared as the web app compares names) or id (
"g0").- step
A step's id (
"s4").- a
A step's id: what differs from it ...
- b
... to this step.
- other
The tracker
bis in, when it is another one (a replay);NULLfortracker.
Value
cellucid_trackers(): a data frame, one row per tracker: id,
name, active, removed, start ("opened",
"shown", "replay", ...), head, active_branch,
main_branch, recording (whether changes become steps) and
paused_at (since when they do not; NA while recording), both
derived from the tracker's paused,
steps, branches, groups and created_at.
cellucid_tracker(): a cellucid_tracker, the history model's
Tracker with every field in snake case (head_id, active_branch,
main_branch, paused (NULL while it records, else
at, since when, by, who paused it and everyone who acted while
it was, and draft, NULL in a file), start,
removed, branches, groups, turns, notes,
journal, steps: each a list of the model's records). A record not found is refused naming the ones there are.
cellucid_branches(): a data frame, one row per branch: id,
name, base (the step it forks from), tip, main,
locked, archived, n_notes and created_at;
cellucid_branch(): one branch's record.
cellucid_groups(): a data frame, one row per group (a named run of
consecutive steps of one branch, a folder over them: nothing is merged):
id, name, branch, first, last,
steps (how many), n_notes and created_at;
cellucid_group(): one group's record, with steps, its steps'
ids. Each step names its group (group).
cellucid_steps(): a data frame, one row per step (with branch,
its path from the root to its tip), the root first and every step before its
children: id, branch (the branch it was made on),
parent, kind ("root", "action",
"outside" – a change made outside an action – or "squashed"),
type (the action), v (the version of the action's parameters
it was recorded with), label (what it did, in a sentence),
code (its line of pseudocode, as recorded), origin ("user",
"agent", "host", "session", "replay",
"startup" or "outside"), agent, model,
host, turn, at (a POSIXct), status
("applied" or "unapplicable"), stale (its result is no
longer what its inputs give), bookmark, group (the group it is
in) and n_notes – the columns of cellucid-python's
Tracker.steps.
A squashed step has no action of its own (type, v and
code are NA): it is the net change of several steps merged
into one, of the history cleared keeping the state, or of what changed while
recording was paused; its record's squashed says why
(cause: "steps", "clear", "paused" or
"share"), how many steps it replaced (count) and who acted in
it (by). Its state is exact, as any step's. A step's code is
its pseudocode as recorded: parameters of an earlier version (v below
the action's version in inst/action_catalog.json) are shown and
applied as they were; the web app upgrades them only to replay them.
cellucid_step(): one step's record: by (who took it),
params, outcome, touches, before, after
and reads (the domains' value hashes), kind, v,
squashed, notes, bookmark, group, ...
cellucid_step_state(): the viewer's state after the step, a named list
by state domain ("cells", "mapping", "field-overlays",
"gene-sets", "highlights", "camera", ...): each value
as the viewer captures it, lists as jsonlite reads JSON, every typed
array an R vector whose attribute "cellucid_array" names its
JavaScript type, the numbers JSON cannot hold NaN, Inf,
-Inf and -0. Refused for a share of the steps only. No picture
of a step is ever stored: the web app draws one from the live view when it
is asked for.
cellucid_step_diff(): a data frame of domain, name and
line (what differs, in the web app's words), one row per change; its
attribute "common" is the latest step both paths share (within one
tracker; NULL across two).
cellucid_stale(): the results stale at the head, each
list(step, cause, domains): a step whose output is still shown while
an input it read changed since, the first later step that changed it, and
those inputs.
cellucid_notes(): a data frame, one row per note (on the tracker, a
branch, a group, a step or a turn): id, on, target, text
(Markdown), origin, agent, at, edited_at,
from_reply.
cellucid_turns(): a data frame, one row per turn (a notebook's or an
agent's group of steps): id, label, origin,
agent, model, host, branch,
conversation, message, started_at, ended_at,
steps (how many), outside (how many acts outside the state
it did, such as a vote published, which Undo turn does not take back) and
summary (the turn's first note).
cellucid_journal(): a data frame, one row per edit of the history
itself (a note, a bookmark, a group, a squash, a branch locked, a step
deleted): id,
op, at, origin, label, purged.
cellucid_methods(): the branch as methods text, in the web app's
words (its rules: app/history/exports/methods.js): the tracker's
first note (its abstract) opens it; a squashed step is said as what it stands
for ("changes made with recording paused (filters, colors)", "3 steps merged
into one (highlights)", a fresh start, a shared state) with a sentence that
only its resulting state was kept; when a listed step is in a group, each run
of steps follows under its heading (the group's name, or "Before"/"After" the
group). cellucid_pseudocode(): the branch as pseudocode, one stored
line per step, # --- QC --- and # --- end of QC --- around a
group's steps, # Bookmark: <name> after a bookmarked step (a squashed step's
bookmarks kept from the steps it replaced marked "(on a step merged into
this one)"), and a
flagged step, a change made outside an action and a squashed step (values
only) as comments.
See also
cellucid_read_session(), cellucid_apply_session();
cellucid-python's Tracker, Branch, Group and Step.
Examples
path <- system.file("extdata", "history_golden.cellucid-session", package = "cellucid")
session <- cellucid_read_session(path)
cellucid_trackers(session)[, c("name", "active", "removed", "head")]
#> name active removed head
#> 1 Annotation TRUE FALSE s13
#> 2 Annotation (replay) FALSE FALSE s2
#> 3 Annotation FALSE TRUE s1
tracker <- cellucid_tracker(session, "Annotation")
cellucid_branches(tracker)[, c("id", "name", "base", "tip", "locked", "archived")]
#> id name base tip locked archived
#> 1 b0 Main <NA> s13 FALSE FALSE
#> 2 b1 Without score s2 s8 FALSE FALSE
#> 3 b2 Clusters s7 s9 TRUE FALSE
#> 4 b3 Scratch s5 s17 FALSE TRUE
#> 5 b4 Tidy fork s16 s18 FALSE FALSE
cellucid_groups(tracker)[, c("id", "name", "first", "last", "steps")]
#> id name first last steps
#> 1 g0 QC s2 s3 2
cellucid_group(tracker, "QC")$steps
#> [1] "s2" "s3"
cellucid_steps(tracker, "Without score")[, c("id", "label", "origin")]
#> id label origin
#> 1 s0 Opened user
#> 2 s1 Renamed NK cell to NK in cell_type user
#> 3 s2 Highlighted 40 cells as "Doublets" on page "QC" host
#> 4 s7 Renamed leiden to cluster user
#> 5 s8 Highlighted "T cell" of cell_type (250 cells) on page "Types" user
cellucid_turns(tracker)[, c("id", "label", "origin", "steps", "summary")]
#> id label origin steps
#> 1 py-1 QC host 2
#> 2 claude-1 Find markers agent 3
#> summary
#> 1 <NA>
#> 2 Ran markers on cell_type, kept the T cell markers and coloured by CD3E.
cellucid_step_diff(tracker, "s5", "s13")
#> domain name line
#> 1 field-overlays Fields and labels Annotation "cell_type (merged)" made
#> 2 active-field Active field Active field changed
cellucid_stale(tracker)
#> [[1]]
#> [[1]]$step
#> [1] "s4"
#>
#> [[1]]$cause
#> [1] "s13"
#>
#> [[1]]$domains
#> [1] "field-overlays"
#>
#>
cat(cellucid_methods(tracker))
#> Annotation of the golden sample: *T cells* first, then the `leiden` clusters.
#>
#> Single-cell data were explored interactively in Cellucid (version 0.9.6). The dataset “History golden” (600 cells and 4 genes) was opened in full. The 7 steps applied are listed below, in order. 1 recorded step no longer applied after an earlier step was removed and is not included. The complete history, with every parameter, can be reopened from the accompanying Cellucid session file.
#>
#> Before QC
#> The following 1 step was applied: (1) renamed NK cell to NK in cell_type.
#>
#> QC
#> The following 2 steps were applied, in this order: (2) highlighted 40 cells as "Doublets" on page "QC"; (3) added the continuous column score. Steps 2–3 were taken by a Python notebook through the Cellucid viewer API.
#>
#> After QC
#> The following 4 steps were applied, in this order: (4) ran Marker genes; (5) kept the gene set T cell markers (2 genes); (6) coloured by gene CD3E; (7) merged B cell into T cell in cell_type. Steps 4–6 were taken by an AI assistant (Claude, claude-sonnet-4-6) at the user's request.
cat(cellucid_pseudocode(tracker), sep = "\n")
#> # Cellucid 0.9.6 · History golden
#> # Tracker "Annotation", branch "Main": 8 steps
#> rename_category("cell_type", "NK cell", "NK")
#> # --- QC ---
#> highlight_cells(<40 cells>, label="Doublets", page="QC", color="#e41a1c") # Python
#> push_column("score", kind="continuous") # Python
#> # --- end of QC ---
#> run_analysis("markers") # Claude
#> gene_set("T cell markers", ["CD3E", "NKG7"]) # Claude
#> # Bookmark: Markers saved
#> color_by(gene="CD3E") # Claude
#> # No longer applies (There is no highlight "Gate" on page "QC"; its highlights are "Doublets".): set_highlight_enabled("Gate", False, page="QC")
#> merge_categories("cell_type", "B cell", into="T cell")
#>
state <- cellucid_step_state(tracker, "s13")
names(state)
#> [1] "cells" "mapping" "field-overlays" "gene-sets"
#> [5] "views" "active-field" "filters" "colors"
#> [9] "visibility" "highlights" "camera" "camera-path"
#> [13] "settings" "analysis" "layout"