Skip to content

Selecting neurons

ds.ids(720575940604407468)          # an ID
ds.ids("DA1_lPN")                   # a type
ds.ids("/^AOTU00.*")                # a regex
ds.ids("super_class:visual_projection")   # any annotation column
ds.ids("DA1_lPN", side="left")
ds.ids(NeuronCriteria(type="DA1_lPN", side="left"))

The first five desugar into the sixth. See the tutorial for the guided version.

criteria

Selecting neurons.

Two layers, and they are not alternatives - the mini-language desugars into the criteria object:

ds.ids(720575940621039145)      # a raw ID
ds.ids("DA1_lPN")              # a type, matched across spec.fields["type"]
ds.ids("/AOTU00.*")            # a regex
ds.ids("cell_class:ALPN")      # an explicit column filter
ds.ids(NeuronCriteria(type="DA1_lPN", side="left"))

parse_ids is a pure function: it takes a query and returns IDs. It does not mutate the dataset. (cocoa's add_neurons mutated self.neurons, which is what made its datasets stateful and its caches unsound.)

NeuronCriteria dataclass

NeuronCriteria(id=None, type=None, side=None, class_=None, status=None, rois=None, regex='auto', **extra)

A backend-agnostic neuron query.

Compiled per backend: to Cypher on neuPrint, and on CAVE to filter_*_dict where the column lives in a queryable table - otherwise resolved client-side against the cached annotation frame.

That fallback is load-bearing, not an accident: FlyWire's authoritative annotations live in a GitHub TSV, not in CAVE, so type="DA1_lPN" genuinely cannot compile to a CAVE filter and must be resolved locally first.

Source code in connecto/core/criteria.py
def __init__(self, id=None, type=None, side=None, class_=None, status=None,
             rois=None, regex="auto", **extra):
    object.__setattr__(self, "id", id)
    object.__setattr__(self, "type", type)
    object.__setattr__(self, "side", side)
    object.__setattr__(self, "class_", class_)
    object.__setattr__(self, "status", status)
    object.__setattr__(self, "rois", rois)
    object.__setattr__(self, "regex", regex)
    object.__setattr__(self, "extra", dict(extra))

filters

filters() -> dict[str, Any]

Canonical field -> value, excluding id and rois.

Source code in connecto/core/criteria.py
def filters(self) -> dict[str, Any]:
    """Canonical field -> value, excluding `id` and `rois`."""
    out = {}
    for canon, attr in (("type", "type"), ("side", "side"),
                        ("class", "class_"), ("status", "status")):
        v = getattr(self, attr)
        if v is not None:
            out[canon] = v
    out.update(self.extra)
    return out

parse_ids

parse_ids(x, ds, *, side=None, regex='auto', version=None) -> ndarray

Resolve any neuron query down to an array of int64 IDs.

Pure function. Returns IDs. Mutates nothing.

Source code in connecto/core/criteria.py
def parse_ids(x, ds, *, side=None, regex="auto", version=None) -> np.ndarray:
    """Resolve any neuron query down to an array of int64 IDs.

    Pure function. Returns IDs. Mutates nothing.
    """
    if x is None:
        return ds.annotations.ids(version=version)

    crit = to_criteria(x, side=side, regex=regex)

    if isinstance(crit, _MultiCriteria):
        out = [parse_ids(c, ds, version=version) for c in crit.criteria]
        return np.unique(np.concatenate(out)) if out else np.array([], dtype="int64")

    return resolve_criteria(crit, ds, version=version)

is_id

is_id(x) -> bool

Is this an ID rather than a name/type?

Source code in connecto/core/criteria.py
def is_id(x) -> bool:
    """Is this an ID rather than a name/type?"""
    if isinstance(x, (int, np.integer)):
        return True
    if isinstance(x, str):
        return bool(_ID_RE.match(x.strip()))
    return False