From 82c6af7504919f6c808d4b4ce7ff252736675cad Mon Sep 17 00:00:00 2001 From: Philipp Schlegel Date: Mon, 15 Jan 2024 08:43:26 +0000 Subject: [PATCH] docs: improve tutorials, fix some docstrings --- docs/source/api.rst | 8 +- docs/source/gallery.rst | 8 +- docs/source/tutorials/flywire_neurons.ipynb | 7 +- docs/source/tutorials/flywire_segments.ipynb | 419 ++++++++++++------- docs/source/tutorials/flywire_setup.rst | 128 ------ fafbseg/flywire/annotations.py | 13 +- 6 files changed, 292 insertions(+), 291 deletions(-) diff --git a/docs/source/api.rst b/docs/source/api.rst index c4d3d79..712a190 100644 --- a/docs/source/api.rst +++ b/docs/source/api.rst @@ -21,8 +21,6 @@ Interact with the segmentation: fafbseg.flywire.locs_to_segments fafbseg.flywire.neuron_to_segments - fafbseg.flywire.encode_url - fafbseg.flywire.decode_url fafbseg.flywire.locs_to_supervoxels fafbseg.flywire.supervoxels_to_roots fafbseg.flywire.skid_to_id @@ -53,8 +51,8 @@ Connectivity: fafbseg.flywire.synapses.get_adjacency fafbseg.flywire.synapses.get_connectivity fafbseg.flywire.synapses.get_synapses - fafbseg.flywire.synapses.synapse_counts - fafbseg.flywire.synapses.predict_transmitter + fafbseg.flywire.synapses.get_synapse_counts + fafbseg.flywire.synapses.get_transmitter_predictions L2-related functions: @@ -112,6 +110,8 @@ Utility functions: fafbseg.flywire.set_default_dataset fafbseg.flywire.set_default_annotation_version fafbseg.flywire.get_user_information + fafbseg.flywire.encode_url + fafbseg.flywire.decode_url Google segmentation diff --git a/docs/source/gallery.rst b/docs/source/gallery.rst index c9270b6..8e690df 100644 --- a/docs/source/gallery.rst +++ b/docs/source/gallery.rst @@ -12,10 +12,10 @@ FlyWire .. toctree:: :maxdepth: 1 - tutorials/flywire_setup - tutorials/flywire_segments - tutorials/flywire_neurons - tutorials/flywire_annotations + FlyWire Setup: How to get your API token? + Introduction to FlyWire root IDs, materializations and datasets + Downloading neuron meshes and skeletons + Working with annotations tutorials/neuroglancer tutorials/flywire_connectivity tutorials/hemibrain_nblast diff --git a/docs/source/tutorials/flywire_neurons.ipynb b/docs/source/tutorials/flywire_neurons.ipynb index 6b17bcc..92d48c4 100644 --- a/docs/source/tutorials/flywire_neurons.ipynb +++ b/docs/source/tutorials/flywire_neurons.ipynb @@ -2836261,7 +2836261,12 @@ }, "source": [ "These L2 skeletons (or dotprops) are good enough for most morphological\n", - "analyses and NBLAST!" + "analyses and NBLAST!\n", + "\n", + ".. note::\n", + "\n", + " Have a look at the `tutorials `_\n", + " for ``navis`` to learn more about what you can do with the neurons." ] } ], diff --git a/docs/source/tutorials/flywire_segments.ipynb b/docs/source/tutorials/flywire_segments.ipynb index 594a76f..8c2d45d 100644 --- a/docs/source/tutorials/flywire_segments.ipynb +++ b/docs/source/tutorials/flywire_segments.ipynb @@ -8,35 +8,167 @@ "source": [ ".. _flywire_segments:\n", "\n", - "Querying the segmentation\n", - "=========================\n", - "For certain tasks it can be useful to query the FlyWire segmentation directly.\n", - "Before we demonstrate this, a quick primer on terminology:\n", + "A primer on the FlyWire segmentation\n", + "====================================\n", + "\n", + "In this tutorial you will learn all you need to know about the FlyWire segmentation.\n", + "\n", + "Before get started, a quick primer on terminology:\n", "\n", "1. In FlyWire, the ID of a neuron (e.g. ``720575940618780781``) is called the \"root ID\".\n", "2. Each root ID is a collection of \"supervoxels\". These supervoxels are the atomic, immutable units of the segmentation.\n", - "3. Every time you edit a neuron (i.e. add or remove supervoxel by merging or splitting) you create a new root ID.\n", + "3. Every time a neuron is edited (i.e. addition or removal of a supervoxel by merging or splitting) you create a new root ID.\n", + "4. A \"materialization\" is a snapshot of the segmentation at a given point in time.\n", + "\n", + "If you work in the FlyWire production dataset, you will have to deal with the\n", + "fact that root IDs are constantly changing as people keep improving the\n", + "segmentation through proofreading. If you are working with the public release\n", + "datasets, you will likely stick to root IDs that match one of the available\n", + "materialization versions. Please find more detailed explanations below.\n", + "\n", + "FlyWire datasets\n", + "----------------\n", + "\n", + "FlyWire actually has three different datasets/versions:\n", + "\n", + "1. The \"Public release\" contains static snapshots of the segmentation which\n", + " correspond to specific materialization version (see below for an explanation\n", + " of materializations). For example, the first ever public release was\n", + " materialization ``630``. Anyone has access to this dataset after signing up\n", + " through the FlyWire website.\n", + "2. The \"Production\" dataset is where people do the actual proofreading/annotation.\n", + " As such it is ahead of the publicly released snapshots. To get access to the\n", + " production dataset you have to be approved by one of the community managers.\n", + "3. Last but not least, \"Sandbox\" is a training ground that has seen minimal\n", + " proofreading (i.e. is close to the bsae segmentation). Anyone has access to\n", + " this dataset after signing up.\n", + "\n", + "Most functions in ``fafbseg.flywire`` accept a ``dataset`` parameter. As of\n", + "``fafbseg`` version ``3.0.0`` the default dataset is the public one.\n", + "\n", + ".. code-block:: python\n", + "\n", + " >>> from fafbseg import flywire\n", + " >>> # Defaults to public dataset\n", + " >>> flywire.supervoxels_to_roots(79801523353597754)\n", + " array([720575940621675174])\n", + " >>> # Specifically query the production dataset\n", + " >>> flywire.supervoxels_to_roots(79801523353597754, dataset='production')\n", + " array([720575940631274967])\n", + "\n", + "You can change this default by running this at the beginning of each session:\n", + "\n", + ".. code-block:: python\n", + "\n", + " >>> from fafbseg import flywire\n", + " >>> flywire.set_default_dataset('production')\n", + "\n", + "See the docstring for :func:`~fafbseg.flywire.set_default_dataset` for details.\n", + "\n", + "Alternatively, you can also set an ``FLYWIRE_DEFAULT_DATASET`` environment\n", + "variable *before* starting the Python session.\n", + "\n", + ".. code-block:: bash\n", + "\n", + " $ export FLYWIRE_DEFAULT_DATASET=\"public\"\n", + " $ python\n", + "\n", + "Environment variables can be set permanently too. The details of that depend\n", + "on your operating system and on which terminal (e.g. bash or zsh) you are using.\n", + "A quick Google should tell you how it works.\n", + "\n", + "FlyWire root IDs - the details\n", + "------------------------------\n", + "\n", + "Under the hood FlyWire is using chunkedgraph, an octree-like structure, to manage\n", + "the segmentation. In brief: \"supervoxels\" are the atomic unit of the\n", + "segmentation which are grouped into \"root IDs\". Or conversely: each root ID is a\n", + "collection of supervoxels. Any edit to the segmentation is effectively\n", + "just the addition or subtraction of supervoxels to that collection.\n", + "\n", + "Like supervoxels, root IDs are immutable though. So whenever edits are made\n", + "new root IDs are generated which then represent the post-edit agglomeration of\n", + "supervoxels. For example, splitting a neuron will generate two new root IDs\n", + "and invalidate its current root ID. Merging two neurons, on the other hand, will\n", + "invalidate the two old root IDs and generate one new root ID representing the\n", + "combination of their supervoxels.\n", + "\n", + "Importantly, \"outdated\" root IDs are not deleted and you can still pull up e.g.\n", + "their meshes in the FlyWire neuroglancer. This is super convenient but it comes\n", + "with a caveat: you can find yourself with a list of root IDs that never\n", + "co-existed which will be problematic when querying associated meta data (see\n", + "paragraph below).\n", + "\n", + "Here are a couple ``fabseg`` functions that will help you tracking root IDs:\n", + "\n", + ".. autosummary::\n", + " :toctree: generated/\n", "\n", - "Because of this dichotomy of IDs, you have to be explicit about whether you want\n", - "root or supervoxel IDs.\n", + " fafbseg.flywire.locs_to_segments\n", + " fafbseg.flywire.locs_to_supervoxels\n", + " fafbseg.flywire.supervoxels_to_roots\n", + " fafbseg.flywire.is_latest_root\n", + " fafbseg.flywire.update_ids\n", + " fafbseg.flywire.find_common_time\n", + " fafbseg.flywire.find_mat_version\n", "\n", - "Let's illustrate by running some examples:" + "Materializations and the CAVE\n", + "-----------------------------\n", + "\n", + "As established above, root IDs can change over time. So how do we maintain the\n", + "link between a neuron and its meta data (e.g. its annotations, synapses, etc.)\n", + "as it evolves? Principally this is done by associating each annotation with an\n", + "x/y/z coordinate. That coordinate in turn maps to a supervoxel and we can then ask\n", + "which root ID it currently belongs to - or belonged to if we want to go back in time.\n", + "\n", + "This kind of location to root ID look-up becomes rather expensive when working\n", + "with large tables: the (filtered) synapse table, for example, has 130M rows each\n", + "with a pre- and a postsynaptic x/y/z coordinate that needs to be mapped to a\n", + "root ID.\n", + "\n", + "Fortunately, all of this is done for you by CAVE, the *c*onnectome *a*nnotation\n", + "*v*ersioning *e*ngine. The gist is this: (almost) every night CAVE looks up\n", + "the current root IDs for the synaptic connections, the community annotations and\n", + "the various other tables it stores. These snapshots are called \"materializations\".\n", + "Note that the public dataset only contains a limited set of these materializations.\n", + "\n", + "If we make sure that our root IDs were \"alive\" at one of the available\n", + "materialization versions, we can query those tables with very little overhead on\n", + "our end. Things get tricky if:\n", + "\n", + "- root IDs are more recent than the latest materialization\n", + "- root IDs only existed briefly *in between* materializations\n", + "- root IDs never co-existed at any of the materializations\n", + "\n", + "``fafbseg`` tries to abstract away a lot of the complications - in fact the\n", + "relevant functions such as :func:`~fafbseg.flywire.get_synapses` accept a\n", + "``materialization`` parameter that defaults to \"auto\" which will try to find\n", + "a matching materialization version and complain if that isn't possible.\n", + "\n", + "In practice, the safe bet is to pick a materialization to work with and stick\n", + "with it for your analyses. If you are working with the public release data, this\n", + "isn't much of a problem since you have only very few versions and no \"live\" data\n", + "to work with anyway. Use :func:`~fafbseg.flywire.get_materialization_versions` to\n", + "get a list of available versions.\n", + "\n", + "Let's explore this a bit:" ] }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 1, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Default dataset set to \"public\"\n" + "Default dataset set to \"public\".\n" ] } ], "source": [ + ">>> # Import the flywire module\n", ">>> from fafbseg import flywire\n", "\n", ">>> # We will use the public dataset for this tutorial\n", @@ -45,65 +177,140 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 5, "metadata": {}, "outputs": [ { "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
time_stampexpires_onis_mergeddatastackversionvalidstatusid
02023-03-21 08:10:002121-11-10 07:10:00Trueflywire_fafb_public630TrueAVAILABLE718
\n", + "
" + ], "text/plain": [ - "array([720575940629790846])" + " time_stamp expires_on is_merged datastack \\\n", + "0 2023-03-21 08:10:00 2121-11-10 07:10:00 True flywire_fafb_public \n", + "\n", + " version valid status id \n", + "0 630 True AVAILABLE 718 " ] }, - "execution_count": 4, + "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ - ">>> # Fetch the root IDs at given x/y/z coordinate(s)\n", - ">>> roots = flywire.locs_to_segments([[95764, 60326, 4855]])\n", - ">>> roots" + ">>> # Check which materilizations are available\n", + ">>> flywire.get_materialization_versions()" ] }, { "cell_type": "raw", "metadata": {}, "source": [ - "Get the supervoxels making up a given root:" + "As you can see, at the time of writing there is only a single materialization\n", + "available for the public release dataset: ``630``.\n", + "\n", + "This also means that all queries automatically go against that materialization:" ] }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 22, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "{720575940625431866: array([76422587017867444, 76422587017876926, 76422587017875950, ...,\n", - " 79308667131852018, 79308667131870469, 79308667131858012],\n", - " dtype=uint64)}" + "array([720575940631680813])" ] }, - "execution_count": 5, + "execution_count": 22, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + ">>> # Fetch the root IDs at given x/y/z coordinate(s)\n", + ">>> roots = flywire.locs_to_segments([[75350, 60162, 3162]])\n", + ">>> roots" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([720575940631680813])" + ] + }, + "execution_count": 23, "metadata": {}, "output_type": "execute_result" } ], "source": [ - ">>> flywire.roots_to_supervoxels(720575940625431866)" + ">>> # We can also specify a timstamp matching the materialization version\n", + ">>> # which will be useful later when more versions are available\n", + ">>> roots = flywire.locs_to_segments([[75350, 60162, 3162]], timestamp='mat_630')\n", + ">>> roots" ] }, { "cell_type": "raw", "metadata": {}, "source": [ - "Check if root IDs are outdated (i.e. have more recent edits):" + "What if you're given a list of root IDs and want to check if they are still\n", + "up-to-date - or match a given materialization version?" ] }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 24, "metadata": {}, "outputs": [ { @@ -112,31 +319,57 @@ "array([ True, False])" ] }, - "execution_count": 6, + "execution_count": 24, "metadata": {}, "output_type": "execute_result" } ], "source": [ + ">>> # Check if root IDs are outdated (i.e. have more recent edits)\n", ">>> flywire.is_latest_root([720575940625431866, 720575940621835755])" ] }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([ True, False])" + ] + }, + "execution_count": 25, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + ">>> # Likewise, we can ask if they were current at a given materialization\n", + ">>> flywire.is_latest_root([720575940625431866, 720575940621835755],\n", + "... timestamp='mat_630')" + ] + }, { "cell_type": "raw", "metadata": {}, "source": [ - "Update outdated root IDs:" + "Is there a way to map root IDs back and forth? There is! We can take a root\n", + "ID, find its constituent supervoxels and then ask which root IDs they belonged\n", + "to at a given point in time. This is what :func:`~fafbseg.flywire.update_ids`\n", + "does:" ] }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 26, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "c73ab369a05f4d7b9b4d60d5ab1f2d66", + "model_id": "c7ad514ba99b4451aea56331045c92df", "version_major": 2, "version_minor": 0 }, @@ -207,7 +440,7 @@ "2 720575940628913983 720575940636873791 0.94 True" ] }, - "execution_count": 7, + "execution_count": 26, "metadata": {}, "output_type": "execute_result" } @@ -223,19 +456,22 @@ "cell_type": "raw", "metadata": {}, "source": [ - "In above example all old IDs are \"ancestors\" to the same current root ID." + "In the above example all old IDs are \"ancestors\" to the same current root ID.\n", + "Note that by default, :func:`~fafbseg.flywire.update_ids` will map to the\n", + "most current version but it also accepts a ``timestamp`` parameter which lets\n", + "us map to a specific point in time." ] }, { "cell_type": "raw", "metadata": {}, "source": [ - "Fetch edits made to a neuron:" + "Want to track how a neuron was edited over time? Easy:" ] }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 27, "metadata": { "raw_mimetype": "text/restructuredtext" }, @@ -360,129 +596,16 @@ "6 Greg Jefferis Lab 957 Varun Sane " ] }, - "execution_count": 8, + "execution_count": 27, "metadata": {}, "output_type": "execute_result" } ], "source": [ - ">>> edits = flywire.fetch_edit_history(720575940625431866)\n", + ">>> edits = flywire.get_edit_history(720575940625431866)\n", ">>> edits.head()" ] }, - { - "cell_type": "raw", - "metadata": {}, - "source": [ - "Fetch basic info for a couple neurons using the L2 cache:" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "metadata": {}, - "outputs": [ - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "2cd27bf1451f46f39780c7740cfa32d0", - "version_major": 2, - "version_minor": 0 - }, - "text/plain": [ - "Fetching L2 info: 0%| | 0/3 [00:00\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
root_idl2_chunkschunks_missingarea_um2size_um3length_umbounds_nm
072057594060878884022601533.782784131.71287036.578[452688.0, 468864.0, 235440.0, 248784.0, 17680...
17205759406218357551553020170.9982722315.315272316.174[327088.0, 496400.0, 121328.0, 250432.0, 16840...
2720575940628913983160102.5455369.7566624.365[337952.0, 345424.0, 157808.0, 163248.0, 16404...
\n", - "" - ], - "text/plain": [ - " root_id l2_chunks chunks_missing area_um2 size_um3 \\\n", - "0 720575940608788840 226 0 1533.782784 131.712870 \n", - "1 720575940621835755 1553 0 20170.998272 2315.315272 \n", - "2 720575940628913983 16 0 102.545536 9.756662 \n", - "\n", - " length_um bounds_nm \n", - "0 36.578 [452688.0, 468864.0, 235440.0, 248784.0, 17680... \n", - "1 316.174 [327088.0, 496400.0, 121328.0, 250432.0, 16840... \n", - "2 4.365 [337952.0, 345424.0, 157808.0, 163248.0, 16404... " - ] - }, - "execution_count": 9, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - ">>> info = flywire.get_l2_info([720575940621835755, 720575940608788840, 720575940628913983])\n", - ">>> info.head()" - ] - }, { "cell_type": "raw", "metadata": {}, diff --git a/docs/source/tutorials/flywire_setup.rst b/docs/source/tutorials/flywire_setup.rst index 514cb7c..639abb4 100644 --- a/docs/source/tutorials/flywire_setup.rst +++ b/docs/source/tutorials/flywire_setup.rst @@ -51,131 +51,3 @@ token like so: } That's it, you're done! You should now be able to query the FlyWire dataset. - - -FlyWire datasets ----------------- - -FlyWire actually has three different datasets/versions: - -1. The "Public release" contains static snapshots of the segmentation which - correspond to specific materialization version (see below for an explanation - of materializations). For example, the first ever public release was - materialization ``630``. Anyone has access to this dataset after signing up - through the FlyWire website. -2. The "Production" dataset is where people do the actual proofreading/annotation. - As such it is ahead of the publicly released snapshots. To get access to the - production dataset you have to be approved by one of the community managers. -3. Last but not least, "Sandbox" is a training ground that has seen minimal - proofreading (i.e. is close to the bsae segmentation). Anyone has access to - this dataset after signing up. - -Most functions in ``fafbseg.flywire`` accept a ``dataset`` parameter. As of -``fafbseg`` version ``3.0.0`` the default dataset is the public one. - -.. code-block:: python - - >>> from fafbseg import flywire - >>> # Defaults to production - >>> flywire.supervoxels_to_roots(79801523353597754, dataset='production') - array([720575940631274967]) - >>> flywire.supervoxels_to_roots(79801523353597754, dataset='public') - array([720575940621675174]) - -You can change this default by running this at the beginning of each session: - -.. code-block:: python - - >>> from fafbseg import flywire - >>> flywire.set_default_dataset('public') - -See the docstring for :func:`~fafbseg.flywire.set_default_dataset` for details. - -Alternatively, you can also set an ``FLYWIRE_DEFAULT_DATASET`` environment -variable *before* starting the Python session. - -.. code-block:: bash - - $ export FLYWIRE_DEFAULT_DATASET="public" - $ python - - -Environment variables can be set permanently too. The details of that depend -on your operating system and on which terminal (e.g. bash or zsh) you are using. -A quick Google should tell you how it works. - - -Understanding FlyWire root IDs ------------------------------- - -Under the hood FlyWire is using chunkedgraph, an octree-like structure, to manage -the segmentation. In brief: "supervoxels" are the atomic unit of the -segmentation which are grouped into "root IDs". Or conversely: each root ID is a -collection of supervoxels. Any edit to the segmentation is effectively -just the addition or subtraction of supervoxels to that collection. - -Like supervoxels, root IDs are immutable though. So whenever edits are made -new root IDs are generated which then represent the post-edit agglomeration of -supervoxels. For example, splitting a neuron will generate two new root IDs -and invalidate its current root ID. Merging two neurons, on the other hand, will -invalidate the two old root IDs and generate one new root ID representing the -combination of their supervoxels. - -Importantly, "outdated" root IDs are not deleted and you can still pull up e.g. -their meshes in the FlyWire neuroglancer. This is super convenient but it comes -with a caveat: you can find yourself with a list of root IDs that never -co-existed which will be problematic when querying associated meta data (see -paragraph below). - -Here are a couple ``fabseg`` functions that will help you tracking root IDs: - -.. autosummary:: - :toctree: generated/ - - fafbseg.flywire.locs_to_segments - fafbseg.flywire.locs_to_supervoxels - fafbseg.flywire.supervoxels_to_roots - fafbseg.flywire.is_latest_root - fafbseg.flywire.update_ids - fafbseg.flywire.find_common_time - fafbseg.flywire.find_mat_version - -Materializations and the CAVE ------------------------------ - -As established above, root IDs can change over time. So how do we maintain the -link between a neuron and its meta data (e.g. its annotations, synapses, etc.) -as it evolves? Principally this is done by associating each annotation with an -x/y/z coordinate. That coordinate in turn maps to a supervoxel and we can then ask -which root ID it currently belongs to - or belonged to if we want to go back in time. - -This kind of location to root ID look-up becomes rather expensive when working -with large tables: the (filtered) synapse table, for example, has 130M rows each -with a pre- and a postsynaptic x/y/z coordinate that needs to be mapped to a -root ID. - -Fortunately, all of this is done for you by CAVE, the *c*onnectome *a*nnotation -*v*ersioning *e*ngine. The gist is this: (almost) every night CAVE looks up -the current root IDs for the synaptic connections, the community annotations and -the various other tables it stores. These snapshots are called "materializations". -Note that the public dataset only contains a limited set of these materializations. - -If we make sure that our root IDs were "alive" at one of the available -materialization versions, we can query those tables with very little overhead on -our end. Things get tricky if: - -- root IDs are more recent than the latest materialization -- root IDs only existed briefly *in between* materializations -- root IDs never co-existed at any of the materializations - -``fafbseg`` tries to abstract away a lot of the complications - in fact the -relevant functions such as :func:`~fafbseg.flywire.get_synapses` accept a -``materialization`` parameter that defaults to "auto" which will try to find -a matching materialization version and complain if that isn't possible. - -In practice, the safe bet is to pick a materialization to work with and stick -with it for your analyses. If you are working with the public release data, this -isn't much of a problem since you have only very few versions and no "live" data -to work with anyway. Use :func:`~fafbseg.flywire.get_materialization_versions` to -get a list of available versions. - diff --git a/fafbseg/flywire/annotations.py b/fafbseg/flywire/annotations.py index 1065e23..2f61f42 100644 --- a/fafbseg/flywire/annotations.py +++ b/fafbseg/flywire/annotations.py @@ -331,7 +331,7 @@ def create_cave_table(name: str, voxel_resolution=[1, 1, 1], *, dataset=None): - """Create annotation table. + """Create CAVE annotation table. This is just a thin-wrapper around `CAVEclient.annotation.create_table`. @@ -410,7 +410,7 @@ def create_cave_table(name: str, @inject_dataset(disallowed=['flat_630', 'flat_571']) def list_cave_tables(*, dataset=None): - """Fetch available annotation tables. + """Fetch available CAVE annotation tables. Parameters ---------- @@ -443,7 +443,7 @@ def list_cave_tables(*, dataset=None): def get_cave_table_info(table_name: str, *, dataset=None): - """Get info for given table. + """Get info for given CAVE table. Parameters ---------- @@ -550,7 +550,7 @@ def delete_annotations(table_name: str, annotation_ids: list, *, dataset=None): - """Delete annotations from table. + """Delete annotations from CAVE annotation table. Parameters ---------- @@ -600,7 +600,7 @@ def upload_annotations(table_name: str, data: pd.DataFrame, *, dataset=None): - """Upload or update annotations to table. + """Upload or update annotations to CAVE table. Parameters ---------- @@ -992,7 +992,7 @@ def search_annotations(x, If ``None`` (default), will use in order: 1. The version set by :func:`~fafbseg.flywire.set_default_annotation_version` 2. The version set by environment variable ``FLYWIRE_DEFAULT_ANNOTATION_VERSION`` - 3. The latest commit available on the "main" branch + 3. The latest release available on the "main" branch Please see the online tutorial on annotations for details. materialization : "auto" | "live" | "latest" | int | bool Which materialization version to search: @@ -1951,6 +1951,7 @@ def community_annotations(self): @property def is_empty(self): + """Returns True if no criteria are specified.""" return len(self.criteria) == 0 def get_roots(self):