ꘇ dat.cell
One number out of a table, wired to your parameter
- input
- text
- value
ꘇ dat.cell reads a single cell out of a table by row and column and gives you two things: the cell as text, and the cell as a FLOAT. That's it - and it's enough to turn a hand-authored CSV into a dashboard of named parameters you can wire one at a time.
What it is
The plumbing layer of ComfyUI exists for two reasons per the KB's node-plumbing doc: killing repetition, and keeping graphs readable. A table of values plus a dat.cell per value is the textual version of that - you author your numbers in one place, in a format you can edit and diff and copy into a spreadsheet, and each consumer pulls its own cell. The difference from a PrimitiveFloat is where the value comes from; the difference from a CHOP is that a table doesn't move. It's a constants palette.
The start of this pattern is a node like ꘇ dat.table, whose default text is literally name,value / speed,0.5 / influence,0.8 - the author showing you the intended usage. Row 1, column 1 is 0.5. Point a cell at row 2 and you have your influence value as a FLOAT, and can hand it to any converted numeric input.
Why bother instead of typing numbers into widgets? Because a table survives being generated. Feed ꘇ dat.json a config blob, or ꘇ top.todat a sampled image, and the same cell node becomes a lookup into data you didn't author by hand.
How it works
The row and column are zero-based indices into the table's rows and cells. If they're in range, the cell's text comes out as a string and - if it parses as a number - its value comes out as a FLOAT. If it doesn't parse, the text is still returned and the FLOAT is 0. If the indices are out of range, you get an empty string and 0, with no error at all.
That last behaviour is the node's whole personality, and it's both a feature and a trap. Feature: early in a build, a cell pointing at a row that doesn't exist yet doesn't break the graph. Trap: a table that shrank, a header you added, or an off-by-one row means a parameter that silently sits at zero and looks like a broken wire. The defaults tell you which convention the author expects - row defaults to 1 and column to 0, i.e. "skip the header, take the first column", which is exactly the name,value layout above.
Both outputs are useful, and they aren't redundant: the string is for text consumers (a filename, a prompt fragment, a ꘇ dat.replace target), the float is for parameters.
The inputs and outputs that matter
- input - the
GENERETI_DATtable.ꘇ dat.table(CSV text),ꘇ dat.json,ꘇ dat.text,ꘇ chop.todatandꘇ top.todatall produce one. - row - INT, default
1, 0..100000. Zero-based, and the header counts as row 0. - column - INT, default
0, 0..100000. Also zero-based: the first column is 0. - text out - STRING, the raw cell contents. Non-numeric cells keep their text here, so
namestill saysname. - value out - FLOAT, the parsed number, or
0if the text isn't numeric or the indices are out of range. This is the socket you convert into a widget.
Both row and column are ordinary INT inputs, so the usual ComfyUI move applies: convert a widget to an input and a signal can drive which cell you're reading - a crude but effective way to build a value sequence out of a static table.
Install
One pack covers every operator in these articles. Manager → search genereti (title "ꘇ Genereti") → install → restart ComfyUI → hard-refresh the browser tab. Manual:
cd ComfyUI
git clone https://github.com/languel/genereti.git custom_nodes/genereti
./.venv/bin/python -m pip install -r custom_nodes/genereti/requirements.txt
Use your ComfyUI's Python for that pip call. The requirement is comfyui-frontend-package>=1.53.6, one line - DAT nodes are plain Python string and table work, so there's no model, no server, no runtime to configure. ꘇ-OpenTouch-Operators-and-Lessons wires a CSV into a cell and out to a control, which is the fastest way to see the pattern working.
Common issues
The value is 0 and you assume the wire broke. Almost always the indices. Add or remove a header row and every cell below it shifts; a 0 with no error is this node's way of saying "out of range".
A text cell reads as 0. By design - only parseable numbers reach the FLOAT output. The text output still carries the original string, so check that first when something looks wrong.
Column 1 isn't the second column from the left? It is. Column 0 is the first. The name,value default table puts the label in column 0 and the number in column 1, which is why the defaults read as they do.
It doesn't update on Queue when you expected live values. A table has no clock. If the table came from a live CHOP or a sampled image, the table is a snapshot taken at readback time, and the cell is one lookup into that snapshot.
Alpha pack. Super alpha, early classroom testing, per the README: back up workflows before updating and expect interfaces to move.
Inputs (3)
| Name | Type | Default | Description |
|---|---|---|---|
| input | GENERETI_DAT | — | |
| row | INT | 10–100000 | — |
| column | INT | 00–100000 | — |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| text | STRING | — |
| value | FLOAT | — |