diff --git a/docs/source/_toc.yml b/docs/source/_toc.yml index 3782c38b..fcd90be0 100644 --- a/docs/source/_toc.yml +++ b/docs/source/_toc.yml @@ -24,6 +24,9 @@ parts: - file: advanced/transforms/index sections: - file: advanced/transforms/add_transforms_to_multiscales + - file: advanced/transforms/create_scenes + - file: advanced/transforms/reading_scenes + - file: advanced/transforms/scene_2d_to_3d - file: advanced/sharding - file: advanced/build_custom_pyramid diff --git a/docs/source/advanced/transforms/add_transforms_to_multiscales.ipynb b/docs/source/advanced/transforms/add_transforms_to_multiscales.ipynb index 6737276e..f7b503fd 100644 --- a/docs/source/advanced/transforms/add_transforms_to_multiscales.ipynb +++ b/docs/source/advanced/transforms/add_transforms_to_multiscales.ipynb @@ -157,7 +157,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": null, "id": "2e7d870d", "metadata": {}, "outputs": [ @@ -175,7 +175,7 @@ "source": [ "ms.to_ome_zarr(\n", " \"multiscale_with_transforms.ome.zarr\",\n", - " version=\"0.6.dev4\", # specify the desired ome-zarr version\n", + " version=\"0.6\", # specify the desired ome-zarr version\n", " overwrite=True,\n", ")" ] diff --git a/docs/source/advanced/transforms/create_scenes.ipynb b/docs/source/advanced/transforms/create_scenes.ipynb new file mode 100644 index 00000000..07512e66 --- /dev/null +++ b/docs/source/advanced/transforms/create_scenes.ipynb @@ -0,0 +1,255 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "8b0be7e9", + "metadata": {}, + "source": [ + "# Create Scenes\n", + "\n", + "(advanced:create-scenes)=\n", + "\n", + "This tutorial demonstrates basic usage around writing and reading [Ngff Scenes](https://ngff.openmicroscopy.org/specifications/dev/index.html#scene-metadata) using the {py:class}`ome_zarr.classes.scene.OMEZarrScene` class." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "a49ec1c2", + "metadata": {}, + "outputs": [], + "source": [ + "from skimage import data\n", + "\n", + "from ome_zarr import OMEZarrImage, OMEZarrMultiscale, OMEZarrScene" + ] + }, + { + "cell_type": "markdown", + "id": "98bbabd7", + "metadata": {}, + "source": [ + "We create some sample data, which we will store as a tiled layout in a scene zarr group:" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "e3023c95", + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "c:\\Users\\johan\\Documents\\GitHub\\ome-zarr-py\\.venv\\Lib\\site-packages\\tqdm\\auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html\n", + " from .autonotebook import tqdm as notebook_tqdm\n" + ] + }, + { + "data": { + "text/plain": [ + "(512, 512)" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "example_image = data.human_mitosis()\n", + "example_image.shape" + ] + }, + { + "cell_type": "markdown", + "id": "71e31e2a", + "metadata": {}, + "source": [ + "First, we cut the image into four tiles and convert them into instances of {py:class}`ome_zarr.classes.image.OMEZarrMultiscale`:" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "017d4c59", + "metadata": {}, + "outputs": [], + "source": [ + "img1 = OMEZarrImage(data=example_image[:256, :256], axes=[\"y\", \"x\"], name=\"img1\")\n", + "img2 = OMEZarrImage(data=example_image[256:, :256], axes=[\"y\", \"x\"], name=\"img2\")\n", + "img3 = OMEZarrImage(data=example_image[:256, 256:], axes=[\"y\", \"x\"], name=\"img3\")\n", + "img4 = OMEZarrImage(data=example_image[256:, 256:], axes=[\"y\", \"x\"], name=\"img4\")\n", + "\n", + "img1_ms = OMEZarrMultiscale(img1)\n", + "img2_ms = OMEZarrMultiscale(img2)\n", + "img3_ms = OMEZarrMultiscale(img3)\n", + "img4_ms = OMEZarrMultiscale(img4)" + ] + }, + { + "cell_type": "markdown", + "id": "cf59df32", + "metadata": {}, + "source": [ + "Next, we need to define a coordinate system into which all images are projected.\n", + "This is defined in accordance with the NGFF [coordinate systems specification](https://ngff.openmicroscopy.org/specifications/dev/index.html#coordinatesystems-metadata)." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "994674c2", + "metadata": {}, + "outputs": [], + "source": [ + "coordinate_system = {\n", + " \"name\": \"world\",\n", + " \"axes\": [\n", + " {\"name\": \"y\", \"type\": \"space\"},\n", + " {\"name\": \"x\", \"type\": \"space\"},\n", + " ],\n", + "}" + ] + }, + { + "cell_type": "markdown", + "id": "c1d629be", + "metadata": {}, + "source": [ + "We then define translations that move each tile into the appropriate position in the world coordinate system.\n", + "In this example, these are simple translations in the y and x dimensions:" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "d6329caa", + "metadata": {}, + "outputs": [], + "source": [ + "coordinate_transformations = [\n", + " {\n", + " \"type\": \"translation\",\n", + " \"translation\": [0, 0],\n", + " \"input\": {\"path\": \"img1\", \"name\": \"physical\"},\n", + " \"output\": {\"name\": \"world\"},\n", + " },\n", + " {\n", + " \"type\": \"translation\",\n", + " \"translation\": [256, 0],\n", + " \"input\": {\"path\": \"img2\", \"name\": \"physical\"},\n", + " \"output\": {\"name\": \"world\"},\n", + " },\n", + " {\n", + " \"type\": \"translation\",\n", + " \"translation\": [0, 256],\n", + " \"input\": {\"path\": \"img3\", \"name\": \"physical\"},\n", + " \"output\": {\"name\": \"world\"},\n", + " },\n", + " {\n", + " \"type\": \"translation\",\n", + " \"translation\": [256, 256],\n", + " \"input\": {\"path\": \"img4\", \"name\": \"physical\"},\n", + " \"output\": {\"name\": \"world\"},\n", + " },\n", + "]" + ] + }, + { + "cell_type": "markdown", + "id": "4444a8d3", + "metadata": {}, + "source": [ + "We can then create and write a scene like this:" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "d05be093", + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Writing images: 100%|\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588| 4/4 [00:00<00:00, 7.08it/s]\n" + ] + } + ], + "source": [ + "scene = OMEZarrScene(\n", + " images=[img1_ms, img2_ms, img3_ms, img4_ms],\n", + " coordinate_systems=[coordinate_system],\n", + " coordinate_transformations=coordinate_transformations\n", + ")\n", + "\n", + "scene.to_ome_zarr(\"test_example_scene.zarr\", overwrite=True)" + ] + }, + { + "cell_type": "markdown", + "id": "9333cd91", + "metadata": {}, + "source": [ + "....and load it back like this:" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "8b87b923", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(Translation(type='translation', input=CoordinateSystemIdentifier(name='physical', path='img1'), output=CoordinateSystemIdentifier(name='world', path=None), name=None, translation=(0.0, 0.0)),\n", + " Translation(type='translation', input=CoordinateSystemIdentifier(name='physical', path='img2'), output=CoordinateSystemIdentifier(name='world', path=None), name=None, translation=(256.0, 0.0)),\n", + " Translation(type='translation', input=CoordinateSystemIdentifier(name='physical', path='img3'), output=CoordinateSystemIdentifier(name='world', path=None), name=None, translation=(0.0, 256.0)),\n", + " Translation(type='translation', input=CoordinateSystemIdentifier(name='physical', path='img4'), output=CoordinateSystemIdentifier(name='world', path=None), name=None, translation=(256.0, 256.0)))" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "loaded_scene = OMEZarrScene.from_ome_zarr(\"test_example_scene.zarr\")\n", + "loaded_scene.coordinate_transformations" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "cd5dda7c", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "ome-zarr (3.13.12)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.13.12" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/docs/source/advanced/transforms/reading_scenes.ipynb b/docs/source/advanced/transforms/reading_scenes.ipynb new file mode 100644 index 00000000..c177c476 --- /dev/null +++ b/docs/source/advanced/transforms/reading_scenes.ipynb @@ -0,0 +1,92 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "28740944", + "metadata": {}, + "source": [ + "# Reading scenes" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "3222cfcb", + "metadata": {}, + "outputs": [], + "source": [ + "import networkx as nx\n", + "\n", + "from ome_zarr import OMEZarrScene" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "a9bebd85", + "metadata": {}, + "outputs": [], + "source": [ + "scene = OMEZarrScene.from_ome_zarr(\"https://radosgw.public.os.wwu.de/s2v/P2A_B6_M2.ome.zarr\")" + ] + }, + { + "cell_type": "markdown", + "id": "7e3c003e", + "metadata": {}, + "source": [ + "This step requires matplotlib" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "a9277576", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAApQAAAHzCAYAAACe1o1DAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjExLjAsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvlcelbwAAAAlwSFlzAAAPYQAAD2EBqD+naQABAABJREFUeJzsnQW4FNX7x8+9dEtjgKggKmIjtmInCgaoiP5sBVtRMcAOVAxE7P7bha0oIgoiNmIQEioK0h0X9v98Dr7Xc+fO7s7s7mzc+36fZ72yOzs7c+bE93zfKorFYjGjUCgUCoVCoVCkiOJUv6hQKBQKhUKhUCihVCgUCoVCoVCkDVUoFQqFQqFQKBRpQQmlQqFQKBQKhSItKKFUKBQKhUKhUKQFJZQKhUKhUCgUirSghFKhUCgUCoVCkRaUUCoUCoVCoVAo0oISSoVCoVAoFApFWlBCqVAoFAqFQqFIC0ooFQqFQqFQKBRpQQmlQqFQKBQKhSItKKFUKBQKhUKhUKQFJZQKhUKhUCgUirSghFKhUCgUCoVCkRaUUCoUCoVCoVAo0oISSoVCoVAoFApFWlBCqVAoFAqFQqFIC0ooFQqFQqFQKBRpQQmlQqFQKBQKhSItKKFUKBQKhUKhUKQFJZQKhUKhUCgUirSghFKhUCgUCoVCkRaUUCoUCoVCoVAo0oISSoVCoVAoFApFWlBCqVAoFAqFQqFIC0ooFQqFQqFQKBRpQQmlQqFQKBQKhSItKKFUKBQKhUKhUKQFJZQKhUKhUCgUirSghFKhUCgUCoVCkRaUUCoUCoVCoVAo0oISSoVCoVAoFApFWlBCqVAoFAqFQqFIC0ooFQqFQqFQKBRpQQmlQqFQKBQKhSItKKFUKBQKhUKhUKSFqul9XaFQVHYsXVlips1dalaVrDXVqxab1o3rmDo1dGpRKBSKygSd9RUKRWhMmrXYPDt2hhnx62wzY94yE3M+KzLGtGpU23Ru18yc2KmVadu8nrawQqFQVHAUxWIxdy1QKBSKuPh93jLT77XxZtTkOaZKcZFZszb+9CGf79mmibm5awfTslFtbVmFQqGooFBCqVAoAuH5cTNM/2ETTMnaWEIi6UcsqxYXmeu6tDc9OrbS1lYoFIoKCA3KUSgKGA8//LDZYostzLJlyyL9ncEjJpkrXh1vVpasDUUmAcfzPb7PeSpK+7z66qtml112MStWrDD5invuucfe/5o1a0y+4oEHHjAHH3ywWbt2bYVqg8cff9z+7uLFiwvy/AqFqeyE8oUXXrCDjNeXX37pe8zpp59uP991113jfpfX1ltvbfbZZx9z7bXXmnnz5sX9rTFjxgS6tj///LPM+RO93nzzTfudWbNmmSFDhph9993Xvv/UU0+ZdMEENHjwYNO1a1ez0047mY4dO9r/v+qqq8xPP/2UkTaJ93r22WdDX++MGTPMpZdeag444ACzww47mKOOOsrccccdZs6cOUmvtXPnzua6664zCxYsCP27PNezzz7b7L777rav9OzZ0wwfPjzpPW+77bZm7733NmeeeaZ57rnnIiUcc+fONb/++mtki7Eok3d8MDHhMWuWzjeLv3nb/P1//cyfD51tloz/yPc4zvPge19nvE9nu314ppdccok59NBDTc2aNe17zz//vL2fkSNHljv+jDPOsJ+9/vrr5T7r27ev2WqrrcyiRYtMpvHPP//Y+8+UZ9Ps2bMtAdxvv/3s/UBqEmHmzJnm8ssvN3vssYfp1KmTueiii8xff/1V5pju3bvbsZbsXPnSBmH7XlRENurzKxSmsgflzJ8/3w6yatWqmccee8zsvPPOZT6HoD355JOmqKjI1K9f3/e7fA8CsXLlSktKr7jiCkuEvv322zLfkeOXLl0a6NqaNWtWbkE59dRTzffff2++/vrrMu9vsMEGZvz48XbnfuSRR9qF67LLLvMlcWHw2WefmWOOOcY0adLEnHfeeWb77be3bQWRfPTRR83NN99sF0Ym+XTaRI73okWLFqGu9+OPPzaHHXaYJb6Qyo033theK9d59dVX27avUqWK72+z6I8ePdpceeWV5v/+7/9sG9etWzfQ7z7xxBOWDNIOPCPOxf1CavndG264Ie49l5SU2EWM3+aZ0Vb8PsQ004C0QrDr1KljovKZxMydCKtmTzOzX7zW1Gq7i6m12U5mwYjHzNoVS+Ie2/u4k80Jx3TLWJ/ORfswh0CWevfuXfpehw4dbD9477337IZCwIL/4osvWpX0rbfestfjgs8YQ975KN/AuNt///3tfHT44Yebiy++2JKaeIAkHnLIIfbY66+/3jRu3Nh8/vnn5oQTTjAjRowoPa5Ro0bm5JNPtmPqf//7nykurhg6B/MG957vz1WhyBQqHKEUMJGhHN19992lCgJ45plnTO3atc2OO+5ofvjhB9/vtmzZ0u6+AWoTC8I555xjnn766TILSFhA3OS8Aq4Fcut9H7Rr1878/vvvdoKFCKaLKVOmWHIGyUYBddsFYnniiSdaUgkhSrdN3OPTAepGvXr1zPvvv2/bCmy33XamW7dudvHxUx3c3+ZYrvX888+3JCDo82PRO+WUU8q8t9dee5mJEyeagQMHWlJZo0aNuL8LUEfPPfdc+5d2p7+1apVZH0IWY15RgQAcfCYToVrjDc2GvZ8wRUXFZsXvE5Ie26rPEya2WVOzS7vVJmpE1T6odDxTSJKgffv2pnnz5nYT5OKrr76y6uNpp51W7rPffvvNTJ8+3VxwwQUm39GmTRs7H7GB++KLLxIey/2yceX1yCOPlL7P3IFa68VJJ51k7rvvPvPOO+9YElYREPXYVCjyDRVjK+iDXr162UnNqwiiPKE6CTkJAsysADKRTVSvXj2ju3VUgiVLlpgHH3ywDJl0waLXo0ePvGkTFtvNNtus3PPi+lEMq1ZNvifC1Bb2Wml7P6Acr169OrAJtWHDhnahXLhwoTXTZ8NHkGd86623WjWJjQLuDGykvOQbVwKINu0jGwqXKJAaiGjuZD6TRVWqWTIZBBy7NlZkz/vH/MR+jXfddZe9N9oaEo/6C6lnowjYKPA+yi++jLhxBGkfOS/twbPh+7h9XHPNNVaBD7Ixw6qA9cALNg8o4a75GhJJv4FITZ061UybNq30M1HqMP8L6Cs33XSTdS3ZZpttLMF65ZVXyv1W0OO8QBE+4ogj7PfoA2HGhFgDkgHzNQoubjR+G2svsEBAvrzXj3sOz6pPnz6+fpGMRcYVfYN+3L9//4T+srhayPPm2lx3FH6bc3qtReCTTz6xn3344Yf231hGbr/9dmuxkDGG64Y7L8TzcaRv3HLLLdZtgA3vcccdV2ajwWZf3Ge23HJL2zZsnv2uS6HIJ1RYhXLDDTe0gx0CKQRp3Lhx5scff7SECpNpUDAxgqZNm5pCBYsnExVmuU033TThsUEWjWy1CQslpuPvvvvOTr4ugpJtfFeBqyalglGjRplhw4ZZM2qtWrUCfw//MYglKms2fATp7z///LNd8FCVIA0slviRysKM+XLPPfe0fQEfU1TgoUOH2muFqLPpIs9kstRAqYLzfjBhVlJ/Pe4NlwHcRSARmJOPP/54a8J+9913reI7aNAgu9DjwtGgQQOrdiVqHzkvBJKNCt+nf1144YW2jSCZifDpp5/av5ASLyAJuIxwjChtkAWIJlYR2pl/Yw6VzxhvYiLHJYdnQN9mA8hminPhv/vLL7+UErSgx3nBporrghy+/fbbGVfMBR988IEl0X/88Yf1EeV311tvPWs5Qo31jh+sNFhOIG4u2DTwrLzWDvGLxGWCcU3foE/j18o5pF1dDBgwwG5Eed5YC7gOyDVqMzjwwAOtVQLSiaXGxb333mv7DWMGsPliU8GGpm3btla5JUgL9xdRm/18HPEf5RxYgRh3qNpsmiGYuOPQBvQFEUKYt5lrH3roIUuEUbvxDVco8hEVllACJgcGPoQCgsmOcfPNNze77bZb4HMwAeDbw8LDQlaoYOJksmNhSxdB2oQF008FhtQyAQcFC8VBBx1kd+moU0yqLMwoOkF8k3j2TNwsoOIXGgYshpBI2o8XJISApDBgscT3k4U+aqDOQLRY6I4++uhSMyOKFGqOAPIEySLICBIGWOhYvDDTczxJy6Mgk4DzfvP7/EDHsmnBfxaw4EIqCZbiOnGJkPch7PQXl1AmAuTO/T6EBFKNupvI5xKFUlwcvBClEeUR4rZq1Sq7IYKQoKbTf/lMCCXkh/4szwC/RIgLGwIIGaDvA64Vywu/G/Q4F/wWfQIiLH6bUQEVFnIOgWT8MY5Q2PiLHylt4FUqIbc8Q8iWWB64Ru6RZ+UHPmdMyjOkr9DuqIWoei4gsUK0OZbxyObhtttus+fhN+g7iBConmwCZQ5h3qLPQUhRsbkHRAlM+jLG+F13jPmBccf8CcFmTZLnxnOR73r9aVEp6VeQzzvvvDOy4CWFIl1UWJM3wPmdgYmfH6YNlAOvX5wfmOzZEW+yySZ2UmZiZDJGBShUsLABPxMxvpBulDL/TrdNWETYZXtfEKswYBKdPHmyDWphYiWCFhMRihWKg58PpXut/B7HoMbgkxoWRKVy3SzALCioQZgZw4LF0883NdNg0USxYUElAMJV5mQBX758uV3QMdMJkREwPiDOH30yylbAiRKzFgaLfud5e90tWOS9GwTeRxEKCu/3IRmQBdck7QcJIkJx8wLFt3Xr1qUmTFwIIPmykcPMLJ9BaCDwQkIhFK+99polYUISBTwr+g8bgKDHuYCEoMBxz4yFqANFmG+4bwgcqiEklvGDuwH9EhcML2hPxqobpIUCy1gW8uXn6+wCv1ZM5xC+IM+b68QNQcAmhfGBv7UAdZA2xR0I4DsNceUe8G33G2Px2oTNKUFNfvfjfvfll182xx57rO3TzHu8sDRkY1OqUKSKCq1QsptkEmFyYJLH54idezJAhvDJwU+GCQA1DlLhZ+IqFBDVzYT1999/l/uMSV/MNKglmG/SbZNMBeXIc4RUCLFAaWVx4ppYUDFB+10rJi8mfr+FPyjWX399++JeIAMs5iiUKApM8kGBiRISHDVQQ1966SW7MGIS5d5RdlmcWHxZoFG2WCD9zJ1C+MdPmmpiprwCl0kE1T432mijMv+W5+n3Pv6jkEJvwJQfvAqeBFB401F5IZkCGAteQg4giBA4iBHkkXYWNxP6ECZ8iK/4T2ImFzMuZOajjz6yZk3ZLPFXzKaM36DHucAdgDkQhSuoH2Q6EHUPgucC5RuwMfQqiJItI54a6Qc/lZj3vKmJgj5v2pPxghmcOZH2JKgIYue63DDG2Hij6tPv+ItaictBPFccfgdhg41uIrBRZn4l8A8fZ66TZ8Zmj+euUOQrKjShBAxCfCZJHcMOPd5ONx4ZgmBBIjBvsECjChQiIJOY2/AjZdF10+e4CzOEJN/bhMUKPydUQ9QWL6HMJJn1AqUJxQIfrKCEEh8p1AUxj0UNfLAmTJhgTbMoKGwAMOVheqXdZMGGmHshaWBq1IomDVEqiEeA4r0fNN9gqt+XOQRiHo9QkkJKfPlcNxPXj5IXxFfSScmYhIRBOv3ABkmUrGTHuUCxIzMCgUSYb6NWKMmryVzjdXuRf/sFP9GejO0w/smQdq97Au8RbZ/q82Yzhh8yz4cx4hdcxLxHWjei9GWMkfqI/2d+8APPnfk12YYFH09ctdgYu+BawrSNQpFtVGiTNyD6E3KBGSuIudsP7BTJn4jpppCTyOKHhgqQiWjjbLUJPm2JTPjZzlknkeJhghlQHIA3UjVq4I7AIkdADn6omEkBigfmfxZM72KKqZSFd4edCleNjxqSX5UcrH4QEzabnbFjx5YhlOJHibqISsf8JCQBkoc/HefFz9ivMADuDEGPc4EyiiKKnyjXg8oZJbp06WL/fvPNN2Xel0hlgu28IOAkbK5WbxDPpEmTrDtEGD95LyDezG1svnhhIfGa1gUoz1i9MFFD8GWMxSOUPDcCyGT+8gLLAa4CWEVcsEHk3hSKfEaFJ5SAhRPHbglSCAt21f369bPnwB+zUMGEhwM7foA4x2OGFeAHRGRmMqfybLcJZAwFlChcAYqBqJJes1mmgFkbRU/8oyBeRHESOc3iDBFIBhZvlAZcLlBz3WTXUYGNE5Gvrl8YCyxEGNXIvT8yHrAxEN9OiCfKGm27c/s2xl+rzhyiPn9UwPyJAkjUvx8gA6jXjAuIA/3FBf9G0YLUiblbgEmaMcUzcH0JeZ5sCMUdJehxLlBHuWaJVvY7JpP+6xBv+hcqHsAMTTARZM2bi5JocK7da+2IlzbIVV4hW4B24LyonLjEpAoUYM7zxhtvWBLOuuG6zdBubKTlvuTecGNwx5gfCADi+8xbUr0Ltfb++++3Vg/ZcJAaizaR3+P+Nbpbke+oFIRSfOCC5CyMh7POOsv6l0Fw4u0uowDRg1w7xASQXkJUiFR2rJBJlBPUAO4H8x2+VZjbcDrnPm+88ca020QCY7yvoOcWkL4DkxYLIGYsrhd1EJIEARIlJNNg0aetMGni88Q1cL8sVJgM/VwD5J5RjVjUOAfqLWYwXC6yAfH5xL2DRZBnS+ogfF1d4o/igp8f73GP+NiyyLHgE5Fcp0ZV06pR8FytMx/tY0suznlznfq9cMxL9t+8Vs/70/fY+W/fmZE+nW0wj/CscbmIF2iFSsnmTALDXIgvrhznAv89lEvagf6O+wbPB4WZvi+m3KDHeUEbSyAJZtuweWQhpZxDUrGxwZJn5waMYDlgnEhQCW41jFuuEVWR/uaCoDvGmMxz3rRBQq684Pchf/hS46MMqWRjHO/+g4KxLmNcgnEE0t64D8gYQ6kkH2Wy0rKow1wf94SKzHm4bv4tvpXMeZBuzsnnfIc51huApVDkG4pi2S5wGjHY9eGQziCPl7wbMEHhIM1i6/0uE59fyhs+4xg5d7Ljg4DdJ47WpDPyAxN+vCTaTDjxEnAHATtjVEomTiYwvwjFVNskHiBaqU72XCsme77vl9YlE8/DCwgDzwizZLyykd57xi+OhTMbVTJYQFGcMGF7SS5BaCRRjvdsBZBzCA6LvrvpGjBsgnl67PRAqYMsaYz599Oq67WwCc3dY4tNzBy57Qamz75t4/ZpFDx8Or3+sPig8Yr3vtsWfu0T77z0LZ51kP7D/MGYJcWMNwpd/N3or2zUvMFDjGchcmw+4vn24evMtcfr70GOi9dWKH88d8znYYhKovkIQuQXDEW70hYQKD+fU0gjyh6lOPEf9GsrzMWu/zvKJ9kW6Lf0WcYfx/rdS7w2wLSMb7Pf8+aaOBfPjywT8XzLGV+MM78xJn2PfuLnmkMf4fuQRr/P+T5rA9fB79PnmI+Ya4OcX6HINiocoVQoFJkBlXIOuHtdEu8oMPyivUybZsEjevMNuI+gkuM6UNkW9KUrS8y0uUvNqpK1pnrVYtO6cR2raqcCUlyRngu1NegmzEsoo3CTwh0Bi0q8JPEKhaKSRXkrFIrU0LZ5PbNnmyZm9G9zM5rgnCo5u23auKDJpJAaTLSoWZWBULLBoHoSCe/JUer2CPQ7XCQ6t2tmTuzUyvadoKBEKBHT+VL3GqXz7rvvtuotpm+FQhEMSigzhC+//DJpjkv8jiTit9B/Nx1U5rYKcg34i8YL+Mj2dZasiZnf5y8zfnaMOlvuadbbs6zPWxBULS4yN3ftYAodmHejSk+VLRCFHS+CWXDQ4UeZeVt2tfXX45Xi5J3p85ZZF4knxkyzGxGeccsAfrj55BuIPya+n5iayT/p9fVUKBTxoSbvDEH8cRIhHf/BfPvddFCZ2yrINUBU/PL05eo63x4/09z1YfngjeKadU2VOusSWIfBbd06mO4do6khrQgHiBN5UuOBZz9k9F/G1G4YSqWGeLJxuK5Le9Mjgmcdzy8yXYhvPX6viXzwFQpFeSihVCgUSTF4xCRzxwfhIoL9cNmB7Uzvzv8FwinCg4hogjnSSY2TzWd+6YGbmz6dywZfFWr74FtJRLZfedp8AYFiBO+cfvrpJl9BsRHy5OLuUJHa4Pnnn7fBUiTHL8TzpwsllIqCB/khyeGGshcvPQ81hFlk3JQn7ncFRBijTpB2xy+qW47Hfy5IMADH8p0guPDCC0vz3bFokWOPaFxyDWbCLEhaF3JrEhlKNDD3SaJlb0m6eG2yrOlWZtDof0zJ2lgZtWrZr6PNqtn/5b30osGOh5qa9Rub67u0D6xM4pdI8m8CNVBrWXxIt+ONEvZeK32AayV9TiqlLlFm+V0ii2kjasnjguCF+7tE4BIlTBQzx9OmUZY3PPzww62S5uZmzTSeHzfDXPHq+KTHrZ77h1k++UuzdtVyU3e7g03VemUTqruq9Hb1l2e8T2ezfYhWJ6KaPK+MVUC+SMYqgTveZ04BCSLwyQvqViYDJEwnoEhK3mYSjBNUVurIZwqMQ1wBmEMhad7MBWGPve+++2xuXongL4Q2CJp/dfLkyTZQrxDPny4qvie5osKDxZ0yZSRa//zzz8t9jsM/iYg5hh2e33clnyBmNHLbkTuQfHDxfite/sEgIHL0mWee8f2MHH3UDD7yyCNtvWB+i0Tu6YASjOSyIycgEz3pSkjKzIJHqhdUAjc5drw2ueCo3c3pTafZgBoxa4JlE0ebhZ8/Z2KetEGSaqXjxo3M8Iv2Dkwm8d8kdyHlIr///nubEoZclRAQIqtdeK8Vskz78vyIHg5blQlCSH5O0tyMGTPGJtqGIHrzILq/S6IM2k+SYEPQyeUZL71OusDnMUp18vd5y0z/YeuShcfDiuk/mJmPnWdmv3KjWfrr5/b5r1kyL+6xJx/R2Rx2eJeM9elctA8pjci3654bMtm/f/9yFYG4P4gn9+r1h4aYQkg//TS6DAqZAtdOfk2KYsizi5cTNMyxbCgYHyTor0jo0aNH3qqH2YAG5SgqBFAHyDWIqcNbvg2CQO42lzR5geIoPlOQBCrh9O7d26od6fgqUmLOW2bu1ltvtflP/YJq8I3kHiCVHEfpvnQAceReyO8IsfSWdGMHT3lG2sYbZevXJtf0vcj63C0yW62L+J0420hl4vV2626KqlanrJDZuEkd03nzZqbnLq1CRXOjTB577LFWFUW9cBVJCCKVfPzgXivttvPOO9sIXZJPB1UqaXOqz7i+c1SU4n02JKhRiX5X2mngwIFWeUJJgFhmGsmCaNJFv9fGWxU6EfCfbXLYRaZ6801tEvtVM39NfOzhF5pdd93ZtP9nRNp9OhftQ79kw3H88ceXed4kpodQspmgeIBA6rRLiVO3AhCJ5VEnvUnt8xGMP8YcRJENaCLFL8yxtE337t2t6Rt1N1Ge3EJCD8f6VRmhhFJRYQAxIjcdi7jUR2bipnoFPk+kAgkCTNnU86XuMItfVNV44lVGyiTOO+88q4hQY9hLJgEkETN4MvO9X5sM6NLeDDDtTY+vHzYvTDDmhTN2MS8+/5x5YvBA88msmXGTQScCJIxgICr2eM3bRJ37mZ/9FiuSjUP2UBlRe4PAr5wmiiVqJ0QzCGgn3C4wSWHWO+WUU6wynA0fQZ4Lz4dAG4gMbhvewgeMh/fee8+WBWUR557dutekBiKaOxkgkkEhx3LeFlUSB5vJhoFKRPRLLA70W56n3AvPlPdxD+F90vskax/3vOPGjbNVhnBpwIToNy68oMY9ieC95Xs7depkzdmQRjYfAv5N6Uk2NnzXBZ8Bb9lN7gsShosH/Y5E736uE0GPc4GySn+EGDMnyPyYDH411zNxLKAtuSYqB6FqCthI8gzpv27fdP0iaQOIOc+e8R2v6ARgTED4cUvhebuuFlismG/cZyegj1F3nfbCnUWsJ1SZk2IkuNa4Y+z5BD6OfJfnxhhkk8qGQuZIXEE4LyAFGcIC/QfrSCFBTd6KCgNMpJAn12eRMpNURoFshoHk+0+FFOULMP++8847VmVN5K8Wr4JJ0DapWmXdNLJdq4Zmzw6bmPn//F2mTnwYiBoMsfSDlKcLeq3pAlWXBSdsHXapVU15xkyDxRa1zL1XlBHUWBZPnjspb1i03Ahu1GoWfZRb3sfHEHcH+gcLJEB1FleGTIPzfjtjXf3qeID48cK1gbrXkLgrrrjCtj8ECjMyvne8T2lUFlz8FBO1j3teXCdQFKm9DZnBtQJynQwQEkibq0ICSDklLEV1dI/HzQRfPtoZNxP3MykHDPiM5wA5wcWDa0PhpsylW4Er6HFeUBXqgAMOsMo51xOUTEYN2pINmBBsl1BiLmdD4QJCSb++9tpr7efc/wMPPGCrTXlJu4B7RgHlWPxWed64QLk+05dffrlvmjb6GmIElhvGGDlnIbkyxuhPCADUoHcJ5ZAhQ8qcB4LJc6PtIcJcC32bfuMH+jlkls8ph1tIUIVSUWHAJM1ky8QjNYExdzOQgxIRwMJABRRMW36qVaFA/LowQaWLIG2C7yJlKAE7fszsHA8hCApUJ1QkJuuuXbta8yULJucKCtSYl19+2SqVqTw/lGwWb0gL6gkEjAUgFaXZXbyiAoob5ng2D65pddq0aWVKIWKuRbmjX4iig4qH6ov/MT6CJC3PZBJ7F5x3ypyy5M8PqMGo4W+88Yb9N+1PaUYUavoyfsAAqwOk7KGHHrKKdpCgNJR12glASgj2wvUkGfGHFMYryYnShOqLAoW7DcSdtodQQupRnPCNpj9TppH2d02jkAbegyTKPHXDDTdYwoWv4bBhw0Id5wIfTzYMjEMUbG9d+VyCtuR6vv322zLvo/xB+l110g34YeNEe8u8hEJLe0Ls3AAfNqUomnIsGxDIJ+cW0YExAXGEmLrWD9oY8sfmhQ007c5GhTY+4ogjSo9jY5bMXN+rVy+rPnION82V6/rBM+LlAhWdtQvXAO65EKCEUlGhgImRyYWazCym7777rt3VJgNkiN0yC+77779vd6AEzjRt2tQUKli8gNckKH6GREEK2EF7d8yptAm7eRZQVOEwJNAFBIHFhN9CWUY9Y7OAuYrF388n0r1WnjmLC0pBqv6vBAygFHA+FEr+hqkPLwsb34saqCzAGwAhNZ8BEekQHhZI1zxIO2NuJABtwE232go4UWLBsv9UvHiABPTp06f036hKkAyIoBtoxXt8hpoThFBCPiQ6G2CqhoywaUgG+n68Sj5iukZ5hFCiuKECYg7HHIrLA+9BKAnEwews36GfQpxRZN1NL2MWH26ul6A4IuODHOcmYpcgMa6DDYffPJBrYB3xWjN4rvGKNjAXQAAFkDlcWyBer7/+urVSCZjfKOkpwMWBvu4Sb54Ta8bgwYPtM5a5hbkDRVosW/HGWDKCPmnSJGsl4xq9OVN5Li44Nxkm2MiyKQZcA2ZyJZQKRQ6AAoHKxcLDZMHO3Ov3lAgMZEwUTNqFrE4CMWMnIjWYynCMp53imWCCtokEqDCxM9GmWsmHSfS0006zL4gdJjAUR8yV+BpBjiS9khcsqPgwxkv7FAQu6UBpQiElUChZ9SIX0uZBXAnSBc8NgoJKhdLC/6Oa8RKFEnUunp8b76H6jZswqUw5xVwB1dDr+8lCz724iqu8zwKc6nnpI4wB+lmi8pmoVPHcKFAhIZuQRsYAfyGW8luQHfotEPOuBORIaiP6OJsi+Q3+8sz4i9KGmTTIcUIoeQ9rDaoXEddRprFKB1x3GLci5hWIoYutt97a/vW6LoiFxPu8IY5sLkRZROlGnUd4QKln7KJGovaLqxD+jMwp+Eay4ZUxxl9vn3Qh6X2S+VHfc889liizweNYNqS0C32SjUKhQBVKRYUCgxuF8sknnywNzvBOQH5wo3WZVBjUkFPMEkHyTeYjxNTtl49PzNB8BqHMZJsQKBDELy0ImFDZ2XMtkEgc5FkgxUfR71ozCVQ+lFFM8PiiiXN+MkiOyrCBCqmAZ0HwAGQFJRl/PvKuYqJFraX9gvgEryqJ5Y0p1AsIUbz3g6bwivd9yGQyQglxFVLuBd/Dx5O2RhXDvI1qKIBQknYLJQ7VEKIjypakluIZeu9DTL+QICHNyY4TkLoKckm/wHSarxHlbFTpp0Hh13/j9e14zxugEguhJOMG5BuiyLyIGIFfLhta93uYznl+MsZwjSHHJgokc16qvtxsFsgiwdwGsRUQD4BbRiGhMFdKhSIBMGGIYzSKTViwK2UBwNzBec4///yCbG/MveyyUZ9QYVJV7MK2Cf5umBHDqg9ipkc98KuhzMIJRK3JFsT8lIhwePHwww/be2dDkw3wW6glYkqF0LMBwLUBn2Ixt+HTiZnXBe+hiGy00YbGmMRlQSsr8ImFnLHI+21QaXcyKbDxoH/iPynANw8iiMrORsOt3tKhQ4fS87um3Hh9MNlxAq4Rgov/Hc+bYBE2RvkEzMj4IAbNwiAWA+8zmDBhXc7UdMpwojyyWYYcEtDF3On1aWSMifIP2GCwacdyEi+v8Db/bijxn8TlwQ/4uUJwvVWD8I0uNGiUt6LCASd1yA/+YvHMuMnQs2dPu+skDZE3irSQQCQrpn+CHPwiQWWhymSbcAzKA6alsMD3ErO6N0E95BTVGey1114m0+D8KDleQMzwuWKyJ5VHMqAescBgMsN0jjk0ahDEgs+wC9wTXMUWIkJEtPiKCfDPwhxLwMdmzeqbws1pEC0giCz6ktrFCyEZjA3IjhsNjq8m5J75iH7mqoVskgjyIBrZjRYW9RKfujDHueD5E0jHpuaYY44Jneg/akCYGC9e9RSzPu4y3ihvwFyG+i5g80m74nKQDmHGtxJrBCohBJVAGtcKA+nDl9oFxyeLmG/Tpo09N/OwV+GWoBxcMbwEErJNLs9Cy8+pCqWiQiLILj4RUKOIoISIYdrApJoNUGED0wvArAL4N4t+2IhpmawgDZhv+H+cu4l0ZCJmYcKMI+UC020TCYwRnx8ivSE2LGbi55QMLAxM1JgQ8UPDcZ3JFVMTDu78BibETIOFHjJAmTzxiSNlEOouuQSffvpp3+/JPUPMMUtidoZ4kAvVDSyJEkSkQzZ4vqjDKCmoU9wDKVMEzz33nFWrUFVYfFF6iG7GNwwSXLtGVdOqUW0zPUBgTsniuWbJd+uiZ1f+sc69gX9ThpHk9g12Pdb32KJZv6bdp3MBNhQbbrihJWh+KaQIDiJwjPGL+dRLBMTsDVz1EkD0yErBOEQlwxzOeQiiou+J6hz0OBf0TTZibIaw3JCFIYzFhU2opGASgoevIfMGPqK4wqRyLKAtsZrQ//zSBkHEvZHezF0Ey2F5oc1xL+B4orbTCTpibiObgJTuJdOEd4yhWDKfMcbEBM5vJlsbnnzySTsH4ouNGou1B6WaTTnthHsCJm/mEogr7hXMI5Bq7q+QoIRSUfCA4Ig5NBFYuNzIV/kuu0g/n0BMFCwC7uKQ6PigYALyXocfUFdTVVi9kzDRpShZUssb/yLIGqk0vGQv1Tbxi/QOk65JvktOOSIeSduBiQsFhuhWFmJv1HYmngfgejHToyLwuyzULNAsMCwEXrj3DIEj+AbfOExnUdfyJpWSG2jFostCBOkmCIDrQcUh96DbLlwv6gtkUxKbY351+1jnds3M02Onh0odVGOjrewrGbiubXfqZPY58b+0K154F3IBZMjPVxIlyc1W4Nc+ic6LOkYbJXNn4HnybPFxo//7+euiKEFu/MYs0ceoWRAQbx/GNxhTK/7MKPNcO6ZSNm/uPBH0OG9b0e4EfaBSo2TzgsSEBf3ML5VPKsdCCok8JyDGS74TpQ0CEC8228xlBKJB0rzJ6eP1F9mM+s0XKLmMdzayXvM5VhPmBggeY4wNKGoxZNg9V48ePcpVZMPvmrHJ9aJK8l02dq4yS99hbuVzfP+xbjB3Mq5dK4ff+fMJRbFMZQBWKBQKxzcM3zFvkl9FfoNKOQfcHV2N6eEX7RWqFGc+AUUXsoP1w80EoAgPTMBYBLA6uLkjEwEyyOYhUUnHdICvMa4f+MEWWkLxfIH6UCoUiowDs5w4yysKB22b1zN7tmmS8Wo5nI/zFiqZBPhG4vqQKE2MIhgwgRPIEpRMZgO4FBAMSCCTIjWoyVuhSBGYkb1lw/xMo5lOHZOr3w0D/IzcQIHK3FZBrgF/OLdMYi6vs8ny1WbBmGm+Zu/a7XYz1ZuFc2MAVYuLzM1d10U0FzLcKN9CBebieKUKBfjYRhlQhr9ivoCgHirjYJZGnQxTwEBRFkooFQpFJAolwTlu9QlFYaBBrWrWl3L4z6nVY/fD9V3am5aNdKFWpI54fpGZAFH4BCvhP6lIHepDqVAoMg4CgFAp2fVHEZWtiB6DR0wyd3wwMe3zXHZgO9O7839BWwqFomJCfSgVCkXGQUQx0ZvqR1m46NO5rbm1WwdTo2qxqVIU3meS793WrYOSSYWikkAJpUKhyDggk0TEZqoEoyI36NGxlRl+0d6m1uJ1idOTBevI57tt2th+r3vH4GX1FApFYUN9KBUKRSTA5K0KZeGjaNk88/OQ3ua6QQ+akta7mhETZ5sZc5cZN2QHGtmqcW3TefNmpucurQo6mluhUKQGJZQKhSKywJxCq/SgKI9HH33UJuU+/5TjbGLuAaa9WbqyxEybu9SsKllrqlctNq0b1zF1auhyolBUZugMoFAoIlMoqZbDq2nTptrKBQiiaimfR/UZt7Qd5LH9Bg1yem0KhSK/oD6UCoUiMoUSqB9l4eKdd96xZTDzKW+gQqHITyihVCgUkUBqbCuhLFw8+OCDtpa5Xz1zhUKhcKGEUqFQRFZejUhvDcwpTFC5591331V1UqFQBIISSoVCEakfpSqUhQl8J+vWrWuOP/74XF+KQqEoACihVCgUkfpRqkJZeFi9erWN7u7Zs6cllQqFQpEMSigVCkWkCiX1vKnrrSgcvPXWW+avv/5Sc7dCoQgMJZQKhSIyaKR3YWLo0KGmU6dOZtttt831pSgUigKBEkqFQhEZ2rZtq5HeBYbffvvNfPDBB6pOKhSKUFBCqVAoIo30hlSqH2Xh4OGHHzYNGjQw3bt3z/WlKBSKAoISSoVCESk00rtwsGrVKvPYY4+ZXr16mdq1a+f6chQKRQFBCaVCoYgUGuldOHjjjTdsEJVWxlEoFGGhhFKhUESuUM6aNcvMnTtXW7oAKuPsvvvupcFUCoVCERRKKBUKReSEEmiC8/zGpEmTzEcffaTqpEKhSAlKKBUKRaSg/GKVKlWUUOY5HnroIdOwYUNzzDHH5PpSFApFAaJqri9AoVBUbNSoUcO0adNGCWUeY+XKleaJJ54wJ598sqlVq1auL0cREZauLDHT5i41q0rWmupVi03rxnVMnRpKAxSZgfYkhUIROTQwJ7/x6quv2mpGGoxT8TBp1mLz7NgZZsSvs82MectMzPmsyBjTqlFt07ldM3Nip1ambfN6ObxSRaGjKBaLuf1LoVAoMo5rrrnG1oaeOXOmtm4eYp999rF/P/nkk1xfiiJD+H3eMtPvtfFm1OQ5pkpxkVmzNv5SL5/v2aaJublrB9OykaaMUoSH+lAqFIqsKJTUhp4/f762dp7hl19+MSNHjlR1sgLh+XEzzP6DRprRv63LrJCITLqfczzf4/sKRVgooVQoFJFDI73zOxinSZMmplu3brm+lAoNjIELFiyw/qpRYvCISeaKV8eblSVrkxJJLzie7/F9zlOR2mfJkiVmxYoVJl+xdu1ae/8UFyhUKKFUKBSRo127dqa4uLhcCUYm0ESLiEyyvFavXu37XV4LFy40JSUlCa+B45YtWxb4mpcuXVrmN+K9WKi8WLRokVm8eLHJ9IK7fPnyhMeEbRNUYyrj9OjRw57b/X66159sYQx7rUGRjJB47zFbXl/kYSWK/oEHHojsN1AW7/hgYuDj165cZl9+4DwvOEplFH06W+3zxx9/mObNm5sRI0aUIa9+42nNmjVx5wqZj6IgpjNmzLD3z3jMNLjeoP08zBzphRJKhUKRk0hvCAQTKK/jjjvO93uPP/546TFvv/12ue82a9bMtG7d2rRq1crWDYe43n333eUmTzn+1FNPDXzNJ554oj23vDbccEN7Dv6670PGwM8//2z69+9vttxyS7PeeuuZXXfd1aQLFvEbbrjBbLvttvb+GjdubOrXr2+23nprc8UVV5hff/01rTbZYIMNLJl78skny9wTr0MPPTT09U6bNs2cfvrpZv311zd169a119qxY0dz77332t9Jdq0o2ffff3/o333//ffNkUceaZVWfpN2oha5dwPj/d2WLVva391oo43MUUcdZV5++eXICCYbKmqkMxai8pnsP6zs/fph9ZzfzYJRz5o/Hz7b/D6ou/n76UvjHnv5Y++aC/v2y2ifzkX7XHnllXYMHXLIIaX9gHHctWvXcsf+3//9n+0je+21l28/i4r0RYGhQ4eaTTfd1D47Sqkyz/r5sc+bN8+cdtpptv3lRYAe5DkMlFAqFIqcRnpDAN555x1b8s8LUtnweTxgphWFi9eBBx5oLrroIjNw4MC0r/f1118vo2YRVAT4677/1ltv2fchfiyKr732ms29mS6mTJlitt9+e/P000+ba6+91vqfoh6wIFx99dU2MptFIN02gVxBXL3K66hRo0Jd799//2123nlnM2bMGNt2qD9USOIaCcp67rnnEl4rixpVevr06WPuvPPOwL+LosTCyfd+++03q8agREG2IUAoP/F+V0yMH3/8senQoYPdRBx00EFJleBU0KhRI/t755xzjokCBOCUBDBxLxj9vDFFRaZZt6tM1UYbJjx2zqfPmRG//pOxPp2L9uH50/d69+5d+l61atXMHnvsYT777LNylg/6AoTq22+/LefzzWdg3333NfmO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CoUi81BCqcgb/Pbbb7Hbb789tvPOO9sFoEaNGrEjjzwy9vTTT8cWLFgQq0yAzNEGufbnwt8VUnnSSSflJal89913bTtNnTo1st/o169fbL311rNKIORtr732iuUDuGf8/jC/f/rpp7m+nLwAavpbb70V69atm3Xb4HXsscfafpKP/VehqEhQQqnIS0ybNs06yOMjB2FAgTniiCNsIMT8+fNjFR2iio0aNSrXl2KVr+Li4tgpp5wSqRKYCmbMmGHbCRIRBVCIN91009hpp50W++WXX+xvoZ7nGuPGjYs1b948tskmm9jrquzAjebKK6+0wWw8IwIB77nnntg///yT60tTKCoNlFAq8h7Tp0+3pqvddtvNLhaoDocddljs8ccftya/iho8UFRUFHvsscdi+QBIFKQS3858IpUQvrp161plOwqMHTvW9rkPP/wwdvHFF8caN24cW7FiRSyXIGgKMz9K/qxZs2KVFUSxMwfsueee9hmhIp977rmxr776Sv1IFYocIPryEgpFmqA6yUUXXWRz/v3+++9m4MCBZuHChTZPXPPmzW2VF3LIkZS4ooB8neRYpMRlPuCEE04wTzzxhK0ccu6559pcffkAyt5ttdVWNudpFHj++edtH9t1113t/Z9yyik5TfpOLXHKnVKNasSIEaZZs2amMgERZPTo0bbsJvk1STjO8yAZOSUw77//frPjjjtqOUSFIgfQxOaKggULCFVdXn75ZTNq1ChbFYRKLyR1Puqoo0yTJk1MIWP//fc3DRs2tEnG8wWQKoj8OeecY+tY50MdY67nxx9/NF9++WXGE16zmenWrZvZZZddTM+ePW2Z0c0339xkGxD4yy+/3Nxxxx3m/PPPt1V76O+VBX///bd5+umn7cbxl19+MRtvvLElk1Sxad26da4vT6FQgFzIogpFpjFz5szY4MGDbdAEplkCSQ444IDYgw8+aKM9CxGkOdl2221j+YaHH37YmhjPP//8vDAtDhw40OaIzLQp/pNPPrH3+fnnn1uzaufOnWO5wPLly21gCS4Qd999d6yygMT6r7/+eqxLly52PBOkR8aB4cOH55XbhUKhWAcllIoKByKjhwwZYpMXC7ncb7/9Yg888EBB+ZxJSpx8IG1eDB061JKtiy66KOfXR3UfroVArkwT+latWpUGSJGEP9uYM2dObPfdd7fptIj8rwwgJdOll14aa9asmW138ozef//9FdZfWqGoKFCTt6JCY/bs2bY+L2ZxfM7YRO29997WLI4ps0WLFiZfQY1qamtTs3rDDTc0+YYhQ4aY3r17m0svvdTcfvvtOTN/T58+3Zo93377betPmwmsXr3a+uiddtppZsWKFdaXEv/dbNY3nzJliq0lPX/+fNsXMLtXVCxatMi88MIL1qT9xRdfmMaNG1sXA8za2267ba4vT6FQBIAG5SgqNAhaOOuss8yHH35o/bAefPBBU61aNeuHtsEGG1hyiS/gX3/9ZfINbdu2tX/zJTDHC4Jz7r33XuvX169fP0vWcwH8HOvWrWt++umnjJ3zo48+MnPnzrW+uE899ZQlNtkkk5AqIZDu/1ck0F8+/fRTG+gEeT/77LNLfYb//PNPc/fddyuZVCgKCEooFZUGBOkQHfr++++bWbNmmUceecTUrl3bRpCjAO65556WILGY5QM23XRTU1xcnLeEEpx33nk2QOTWW28111xzTU5IJcrolltumdFI7+eee860a9fOBuEsWLDAnHHGGSZbePXVV03nzp3t748ZM8ZsttlmpiKB8XXzzTfb4CY2dATUsSFBaX7nnXes9SCXkfQKhSJF5NrmrlDkGnPnzrX57A499FCb45JhQc7LQYMG2cTZuQRJtS+77LJYvoPAGNptwIABOfl9kq6TlzFTQTCUvezfv39s1113tcFd2QJ9juCb4447zl5HRQG5O6m6dMghh1i/5lq1asV69eplA580wEahqBhQQqlQOMDxn2o8hx9+uK3OA0miWg8BMiRYzzYOOuig2FFHHVUQz+iWW26x7XXDDTdk/bdJbE6C80wECL3yyiv2Pt544w379+WXX45FDcoCEjXP7/Xt27fCkKwffvghduGFF9qE8DKWHnroodjChQtzfWkKhSLDUEKpUMQB9cOpI07aEiGXqGCocVHWjnbRp0+fWPv27QvmGd144422nW6++eas/u7bb79tfzcTpJ8UPdttt12sd+/esRYtWtj0NVFi6dKltmY9yh3ZCQodlEblPnbaaSf7TIjWJmp7woQJub40hUIRIZRQKhQBgKJC+UHUQvLhsVCyYN52222xKVOmRNaG1CMmZUwhKVaYvWmfqMoh+gGCz2++++67aZ1n0aJF1hx7/fXXx+rXrx+76qqrYlGCNFZsUsijGVU98myA/kl+SPJE0l9J1XXEEUfEXnvttcgJuUKhyA9oUI5CEQD169e35QdJQfTPP//YoA2ii/v372+DJij3RmAKqV4yHelN2hpSBxUKrr32WnP11Vebvn37mkGDBmXlN3kWderUSTswZ9iwYWb58uU2onvx4sWRBuMQ8EP09owZM8zIkSPNYYcdZgoNBNJcd911NoCMyk5ff/21/TcplmhLouTJqqBQKCo+NA+lQpEGlixZYiNTSXVCHkTIyHbbbWeOPfZY+5LUP6li8uTJ9hykPWLBLhRg/bjqqqvMLbfcYu655x6bpilqdOzY0WyzzTa23niqOOKII2y6oJKSEpsVgGcbBYhspiY36XL4DUoJFgrY4Lz++us2Z+Tw4cMtke/evbstgUnN83wox6lQKLIPVSgVijRA/sPjjjvOEkqUyxdffNGmQ7npppvsX5Iy33jjjVaNSgUk7K5atWpepw7yA6SCNrjsssvMBRdcYO6///7If7N9+/ZpKZTz5s2zKaX22GMPM27cOJu/NAqQJJ3NARuPzz//vCDIJBuEb775xvTp08eS4OOPP95uniDv5HAlBdduu+2mZFKhqMRQQqlQZAgoNaiSVPyAXFKdZ6uttrKm8C222MJ06NDBXH/99ebnn38OfE7I5CabbFJwhFJI5W233WbzfEJEhg4dGunv0dYkN081Fyb5H9esWWMT4JOXNNMmaK6L9oCMoei99957Zr311jP5DNRacrNuv/321q2DNiIBORskVFYSvrOpUigUCg3KUSgixrJly2wdZgIWSG0Dt9hqq61snsMff/wx6ffJj0kao0IFqXwkJc7DDz8c2e+8+eab9jdSzR1K7fe9997bPiOeTSaxevXq2FlnnWWv75prrsl5/fNkKYzee+89G+1OdoOqVavGunXrZoOGuA+FQqHwgxJKhSKLIFn166+/HuvZs6eNIoZgbLnllpZkkLPPj2iQx69du3YF/Zy4L9LwkLT7sccei+Q3fvvtN9uekKGwmDlzpr22k046yabv+f333zN2XUSOk9AbYvboo4/G8hWTJ0+OXX311bGNNtrItiPpqu666y4bia5QKBTJoIRSochh9ZBhw4bZiiENGjSwizjEkVQ13333XSm5vP/++20Fn0JXh7ifs88+2xI3ksdHkbqmdu3aNgl9KumZIHzbbLONTXeTKfz555+x7bff3lbeef/992P5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YqlVvnCnrfx2uhOP5et0tk4HXWwVXXu7z1dVzrH5D19kHfYZbm233qfOd5dPf8f22ekGt9377befTZ8+3U4//XR7++23nZhE4O60005266232m9+8xv3nSeeeCIyxnHixIl24YUXuuODZZgYV9z/N910k7PiYvk944wz6oQkkOl/1lln2ciRI5tMln5TRoJSCCGE+AUEI5a51q1bO2smL/BWRUQSFjwvMhFZWDwpg/Tmm286V7svh4RVNCgyWQYQbJdddpnts88+ttN1z9vkB66y+Y9fad1O/n9Wvk6XOudi8fiHbJ0dj7SK9TdzVsr5j1zqBOb6J93hRFqLDTe3Zl02sZ8/fLGeoFwy+Xlrvk4n23vvvd3/jzvuOLdviL111lnH7cvYsWPtvffeqxWUUbz//vu222672V577eX2vXPnzk5UY/GdNm2aCxHg87Db/9lnn7WjjjrKlYRCWIriRoJSCCGE+IXzzjsvMinn3XffdQkruHCxYPLCunfjjTe6GEpviURoRZVDwho5deraxBuEJxbDVu3aW+ez/tc67neuzb37FPtx0rPWYY9T6/xui55bOTEJZS3bWdvtDrJFL95pqypnW/NOa93pbQfsZ4v+7y5bMfcLq9hgrTBctXC2rZg1xdYZfKQtr15jrcvMbcPZZ5/txCSwL4jERFx66aXuO6NHj3YJTsAx+v3vf19vWWJRqT+KW53knoEDB9qTTz4pQdkEkKAUQgghfmHMmDG1VsmGgNDq3bu3e4W55ZZbnMv7X//6l3OTv/flPBtdWWLlbTtZsw4b2oq5n9f7TovudbelWftu7u/qJQvMfhGUrfvuZj+Me8B++vCFWkHJv2nQ2LrfHvZNZZX17baO7b777i6bHdF7wAEH2ODBg2sFYiywYr7xxht28MEHx12W2MoRI0bYY4895qygxGxi0UVcYtEUxY+iZYUQQogcQmY62eTDjjjq18G4RRtbs/LX2pq177eqW7S9pFmF+1uzavmvyzRrYW367W5Lv3jTucVrVi63nz99zSp69LNm7de3ldU1bjnE3uWXX15rISX2cf/993exlbHAnY8ADSb1RIFLG6H88ssv2w8//GBffvmlc4HvuuuutRn0oriRoBRCCCFyCHGW0Lz81yF49U8LraxN+wavs+2A/W1N9Sr7+ZOxVvXZ67ZmRZW12WrPOr+DhfFPf/qTTZ482Yk+XNgk0xx22GEx10ssafv27Z3bPh7PPfecHXLIIc7qGQRhKZoGEpRCCCFEhsE6RyxlFI8++qj7u1HH1kbuM67u6sXfWcteAxv8e806bGAtNtrKJef8NPkFK61oba02G+zWz+/gug5aCslqP/zww50rm6xzn0gUBcuRvBNlyVy1alXt+igdFOTVV1+VoGxCKIZSCCFEkwArW7B2oidYHifWMsQBduzYMenfoiQR7t7XX3+93meIuyuuuMJ17mkx8x2b/dzfXKY2VsZ04PvfP3W9+3ebAftbabMK69GxlbWuKHcWSRJkyDDfbrvtnAv7o48+cm7qo48+Om5Zn7/85S/21ltvuUzua6+91rbeemuXsX7ffffZ8OHDXWLPCSec4BKU7rjjDpeshBWUmp641kkGEsWPBKUQQoiiBvFExjEJMVGQhZxomfPPP7+2zmIQip2vWLGi3vusK1jUPMiVV15pjzzyiF1wwQW2ZP5ia7PlEGu3/eFWUv5rdnlZy7ZW3mFDKyktq/NdluH90or6LRVb9v6tlbXt5NznbfrvaWWlJTZks7VliHBbjxs3zu6++24nEKlBSaY6iUKIwXitF4m1JMv9f/7nf9x2k9hD0hE1LX2WODU8Ed1PP/20jRo1ygYNGuTc4NSpJOM73vpFcVCyJp6dWwghhBAZwWd506XGJ7l8Of8n2/P2NzKyfmIo5/z1OCtbZz3r9vs73XtjR+xivbu0zcj6hYiHYiiFEEKIRmLT9drazr07OWtiuiz7erLVrKhyBc5ZH+uVmBS5QoJSCCGEaERGHtLPytMQlNU/VdqKedNs8RujnHWyTf893PpYrxC5QoJSCCGEyAEk9RA/GE766d6hlV0ztG+D1/vje09b5Qt3WPm6Xa3L4Ve5OMtrh/Z16xUiVyiGUgghhMgD7hr3pd3ycuwi48ly0V597Owh9Tv1CJFNJCiFEEKIPOGxSbPsqjFTrbpmja2uST5nlphJ3NxYJo8cGJ1dLkQ2kaAUQggh8ojZi5baZU9PsQlfLXRCMZ6w9J+TgEPMpNzcorGQoBRCCCHyEEoKjZ44y8ZNX2CzKpdaUFaSwkPRcupMHrd9D2Vzi0ZHglIIIYTIc6pWVNs3lVW2srrG9eamnSIdcITIFyQohRBCCCFEWqhskBBCCCGESAsJSiGEEEIIkRYSlEIIIYQQIi0kKIUQQgghRFpIUAohhBBCiLSQoBRCCCGEEGkhQSmEEEIIIdJCglIIIYQQQqSFBKUQQgghhEgLCUohhBBCCJEWEpRCCCGEECItJCiFEEIIIURaSFAKIYQQQoi0kKAUQgghhBBpIUEphBBCCCHSQoJSCCGEEEKkhQSlEEIIIYRICwlKIYQQQgiRFhKUQgghhBAiLSQohRBCCCFEWkhQCiGEEEKItJCgFEIIIYQQaSFBKYQQQggh0kKCUgghhBBCpIUEpRBCCCGESAsJSiGEEEIIkRYSlEIIIYQQIi0kKIUQQgghRFpIUAohhBBCiLSQoBRCCCGEEGkhQSmEEEIIIdJCglIIIYQQQqSFBKUQQgghhEgLCUohhBBCCJEWEpRCCCGEECItJCiFEEIIIURaSFAKIYQQQghLh/8PRKDerF9KyvcAAAAASUVORK5CYII=", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "nx.draw(scene._graph.graph, with_labels=True)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a2766d6c", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "ome-zarr (3.13.12)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.13.12" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/docs/source/advanced/transforms/scene_2d_to_3d.ipynb b/docs/source/advanced/transforms/scene_2d_to_3d.ipynb new file mode 100644 index 00000000..a5493afc --- /dev/null +++ b/docs/source/advanced/transforms/scene_2d_to_3d.ipynb @@ -0,0 +1,201 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "002e4aac", + "metadata": {}, + "source": [ + "# Transforms with changing dimensionality\n", + "\n", + "A particular and important kind of transforms,\n", + "are transforms that change the dimensionality of the data.\n", + "Common examples for this case are:\n", + "- 2D to 3D transforms, e.g. for aligning a 2D slice to a 3D volume\n", + "- 2D + channel to 2D transforms, e.g. for aligning a 2D slice with multiple channels to a 2D slice with a single channel\n", + "\n", + "The transform that expresses this change in dimensionality is the [`ProjectAxis` transform](https://ngff.openmicroscopy.org/specifications/dev/index.html#projectaxis).\n", + "\n", + "This tutorial demonstrates its usage for the case of a 2D to 3D transform,\n", + "where a 2D slice is aligned to a 3D volume." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ac4f951d", + "metadata": {}, + "outputs": [], + "source": [ + "from skimage import data\n", + "\n", + "from ome_zarr import OMEZarrImage, OMEZarrMultiscale, OMEZarrScene" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "ede90a69", + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "c:\\Users\\johan\\Documents\\GitHub\\ome-zarr-py\\.venv\\Lib\\site-packages\\tqdm\\auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html\n", + " from .autonotebook import tqdm as notebook_tqdm\n" + ] + }, + { + "data": { + "text/plain": [ + "(2, 60, 256, 256)" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "img = data.cells3d().transpose((1, 0, 2, 3))\n", + "img.shape" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "a9445304", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(256, 256)" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "some_slice = img[0, 30, :, :]\n", + "some_slice.shape" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "454e972b", + "metadata": {}, + "outputs": [], + "source": [ + "ngff_img = OMEZarrImage(\n", + " data=img,\n", + " axes=[\"c\", \"z\", \"y\", \"x\"],\n", + " scale={\"c\": 1, \"z\": 1, \"y\": 1, \"x\": 1},\n", + " name=\"cells3d\"\n", + ")\n", + "\n", + "ngff_ms = OMEZarrMultiscale(\n", + " image=ngff_img,\n", + ")\n", + "\n", + "slice_img = OMEZarrImage(\n", + " data=some_slice,\n", + " axes=[\"y\", \"x\"],\n", + " scale={\"y\": 1, \"x\": 1},\n", + " name=\"cells3d_slice\"\n", + ")\n", + "\n", + "slice_ms = OMEZarrMultiscale(\n", + " image=slice_img,\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "a7b4469f", + "metadata": {}, + "outputs": [], + "source": [ + "transform_to_3d = {\n", + " \"type\": \"sequence\",\n", + " \"input\": {\"path\": \"cells3d_slice\", \"name\": \"physical\"},\n", + " \"output\": {\"path\": \"cells3d\", \"name\": \"physical\"},\n", + " \"transformations\": [\n", + " {\n", + " \"type\": \"projectAxis\",\n", + " \"createdOutputs\": [0, 1]\n", + " },\n", + " {\n", + " \"type\": \"translation\",\n", + " \"translation\": [0, 30, 0, 0]\n", + " }\n", + " ]\n", + "}" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "abde22ea", + "metadata": {}, + "outputs": [], + "source": [ + "scene = OMEZarrScene(\n", + " images=[ngff_ms, slice_ms],\n", + " coordinate_transformations=[transform_to_3d]\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "8d723932", + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Writing images: 100%|\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588| 2/2 [00:01<00:00, 1.98it/s]\n" + ] + } + ], + "source": [ + "scene.to_ome_zarr(\"scene_2d_to_3d.zarr\", overwrite=True)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "062391f5", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "ome-zarr (3.13.12)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.13.12" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/docs/source/basic/write_image.ipynb b/docs/source/basic/write_image.ipynb index 0327fa61..99b58b74 100644 --- a/docs/source/basic/write_image.ipynb +++ b/docs/source/basic/write_image.ipynb @@ -57,14 +57,14 @@ "As a last step, we write the multiscale image to disk using the `to_ome_zarr` method, which will create a valid OME-ZARR file that can be read by any OME-ZARR compatible viewer.\n", "\n", "```{hint}\n", - "The demonstrated writer method below defaults to writing OME-ZARR version `0.5`,\n", - "but also supports writing OME-ZARR version `0.6.dev4` and `0.4`.\n", + "The demonstrated writer method below defaults to writing OME-ZARR version `0.6`.\n", + "Writing OME-ZARR version `0.5` and `0.4` needs to be explicitly specified.\n", "```" ] }, { "cell_type": "code", - "execution_count": 3, + "execution_count": null, "id": "ce122c48", "metadata": {}, "outputs": [ @@ -95,7 +95,7 @@ " channel_colors=[\"00FFFF\", \"FF00FF\"], # optional\n", " contrast_limits=[(0, 255), (0, 255)] # optional\n", " )\n", - "multiscales.to_ome_zarr(\"test_ngff.ome.zarr\", version=\"0.5\")" + "multiscales.to_ome_zarr(\"test_ngff.ome.zarr\", version=\"0.6\")" ] }, { diff --git a/ome_zarr/__init__.py b/ome_zarr/__init__.py index 84c34696..07f8a1db 100644 --- a/ome_zarr/__init__.py +++ b/ome_zarr/__init__.py @@ -1,7 +1,7 @@ from dask import __version__ as dask_version from packaging.version import Version -from .classes import OMEZarrImage, OMEZarrLabels, OMEZarrMultiscale +from .classes import OMEZarrImage, OMEZarrLabels, OMEZarrMultiscale, OMEZarrScene # Expose __version__ and fallback when _version.py doesn't exist. try: @@ -12,4 +12,10 @@ # If not 2026.3.0 it must be 2025.11.0 or lower. Name indicates kwargs only contain array kwargs in the dask version. USE_DASK_ARRAY_KWARGS = Version(dask_version) >= Version("2026.3.0") -__all__ = ["OMEZarrImage", "OMEZarrLabels", "OMEZarrMultiscale", "__version__"] +__all__ = [ + "OMEZarrImage", + "OMEZarrLabels", + "OMEZarrMultiscale", + "OMEZarrScene", + "__version__", +] diff --git a/ome_zarr/classes/__init__.py b/ome_zarr/classes/__init__.py index fb26acb1..3a8b13d1 100644 --- a/ome_zarr/classes/__init__.py +++ b/ome_zarr/classes/__init__.py @@ -1,7 +1,9 @@ from .image import OMEZarrImage, OMEZarrLabels, OMEZarrMultiscale +from .scene import OMEZarrScene __all__ = [ "OMEZarrImage", "OMEZarrLabels", "OMEZarrMultiscale", + "OMEZarrScene", ] diff --git a/ome_zarr/classes/image.py b/ome_zarr/classes/image.py index 799e5c3b..167c677b 100644 --- a/ome_zarr/classes/image.py +++ b/ome_zarr/classes/image.py @@ -343,7 +343,7 @@ def to_ome_zarr( self, group: zarr.Group | str, storage_options: list[dict[str, Any]] | dict[str, Any] | None = None, - version: Literal["0.6.dev4", "0.5", "0.4"] = "0.5", + version: Literal["0.6", "0.5", "0.4"] = "0.6", compute: bool = True, overwrite: bool = False, ) -> list: @@ -372,7 +372,7 @@ def to_ome_zarr( shutil.rmtree(group) fmt: Format | None = None - if version in {"0.5", "0.6", "0.6.dev4"}: + if version in {"0.5", "0.6"}: fmt = FormatV05() elif version == "0.4": fmt = FormatV04() @@ -438,7 +438,7 @@ def to_ome_zarr( group.attrs["ome"] = metadata_dict - elif version == "0.6.dev4": + elif version == "0.6": metadata_dict = { "version": version, "multiscales": [ @@ -615,7 +615,7 @@ def images(self) -> list[OMEZarrImage]: def _write_additional_meta_data( self, group: zarr.Group, - version: Literal["0.6.dev4", "0.5", "0.4"] = "0.5", + version: Literal["0.6", "0.5", "0.4"] = "0.5", storage_options: list[dict[str, Any]] | dict[str, Any] | None = None, compute: bool = True, overwrite: bool = False, @@ -840,7 +840,7 @@ def __init__( def _write_additional_meta_data( self, group: zarr.Group, - version: Literal["0.6.dev4", "0.5", "0.4"] = "0.5", + version: Literal["0.6", "0.5", "0.4"] = "0.5", storage_options: list[dict[str, Any]] | dict[str, Any] | None = None, compute: bool = True, overwrite: bool = False, @@ -853,13 +853,15 @@ def _write_additional_meta_data( if self._omero and isinstance(self._omero, Omero): omero_dict = _recursive_pop_nones(self._omero.model_dump(by_alias=True)) + # in 0.4, omero metadata goes in group attrs if version == "0.4": group.attrs["omero"] = omero_dict - elif version == "0.5": + elif version == "0.5" or "0.6" in version: if "ome" not in group.attrs: raise ValueError("OME-Zarr attributes not found in group") ome = cast(dict, group.attrs["ome"]) - omero_dict["version"] = version + if version == "0.5": + omero_dict["version"] = version ome["omero"] = omero_dict group.attrs["ome"] = ome @@ -897,7 +899,7 @@ def _write_additional_meta_data( # Update labels list in metadata if version == "0.4": label_group.attrs["labels"] = list_of_labels - elif version == "0.5": + elif version == "0.5" or "0.6" in version: label_group.attrs["ome"] = { "version": version, "labels": list_of_labels, @@ -1031,7 +1033,7 @@ def _read_additional_metadata( if version in ("0.1", "0.2", "0.3", "0.4") and "omero" in group.attrs: omero_dict = cast(dict[str, Any] | None, group.attrs.get("omero", None)) - elif version == "0.5": + elif version == "0.5" or version.startswith("0.6"): ome_attrs = cast(dict[str, Any], group.attrs.get("ome", {})) if "omero" in ome_attrs: omero_dict = cast(dict[str, Any] | None, ome_attrs.get("omero", None)) @@ -1050,7 +1052,7 @@ def _read_additional_metadata( list_of_labels = ( cast(list[str], labels_json) if isinstance(labels_json, list) else [] ) - elif version == "0.5" and "labels" in group: + elif (version == "0.5" or version.startswith("0.6")) and "labels" in group: labels_ome_attrs = cast( dict[str, Any], group["labels"].attrs.get("ome", {}) ) @@ -1161,7 +1163,7 @@ def image_label(self, value: Label | dict[str, Any] | None): def _write_additional_meta_data( self, group: zarr.Group, - version: Literal["0.6.dev4", "0.5", "0.4"] = "0.5", + version: Literal["0.6", "0.5", "0.4"] = "0.5", storage_options: list[dict[str, Any]] | dict[str, Any] | None = None, compute: bool = True, overwrite: bool = False, @@ -1173,7 +1175,7 @@ def _write_additional_meta_data( group.attrs["image-label"] = _recursive_pop_nones( self._image_label.model_dump(by_alias=True) ) - elif version == "0.5": + elif version == "0.5" or version.startswith("0.6"): ome = cast(dict, group.attrs.get("ome", {})) ome["image-label"] = _recursive_pop_nones( self._image_label.model_dump(by_alias=True) @@ -1198,7 +1200,7 @@ def _read_additional_metadata( image_label_dict = cast( dict[str, Any] | None, group.attrs.get("image-label", None) ) - elif version == "0.5": + elif version == "0.5" or version.startswith("0.6"): ome_attrs = cast(dict[str, Any], group.attrs.get("ome", {})) if "image-label" in ome_attrs: image_label_dict = cast( diff --git a/ome_zarr/classes/scene.py b/ome_zarr/classes/scene.py new file mode 100644 index 00000000..a2285a93 --- /dev/null +++ b/ome_zarr/classes/scene.py @@ -0,0 +1,461 @@ +# the class for storage representation, not exposed to the user +import os +from collections.abc import Sequence +from typing import Any, cast + +import transformnd as tnd +import zarr +from ome_zarr_models.v06.coordinate_transforms import ( + AnyTransform, + CoordinateSystem, +) +from ome_zarr_models.v06.scene import SceneAttrs +from pydantic import TypeAdapter +from zarr.storage import StoreLike + +from .image import OMEZarrMultiscale + + +class OMEZarrScene: + def __init__( + self, + images: list[OMEZarrMultiscale] | dict[str, OMEZarrMultiscale], + coordinate_transformations: Sequence[AnyTransform] | list[dict[str, Any]], + coordinate_systems: ( + Sequence[CoordinateSystem] | Sequence[dict[str, Any]] | None + ) = None, + coordinates_displacements: dict[str, OMEZarrMultiscale] | None = None, + ): + """ + Parameters + ---------- + images : list[OMEZarrMultiscale] | dict[str, OMEZarrMultiscale] + Either a list of images (keyed internally by metadata.name) or a dict + mapping zarr group paths to images. The dict form gives explicit control + over the paths where images will be stored in the zarr hierarchy. + """ + # Coerce list to dict keyed by metadata.name + if isinstance(images, list): + self.images = {str(img.metadata.name): img for img in images} + else: + self.images = images + + # parse coordinate systems and transforms + self.coordinate_systems = self._parse_coordinate_systems(coordinate_systems) + self.coordinate_transformations = self._parse_transforms( + coordinate_transformations + ) + self.coordinates_displacements = coordinates_displacements + + self.metadata = SceneAttrs( + coordinateSystems=self.coordinate_systems, + coordinateTransformations=self.coordinate_transformations, + ) + + self._build_graph() + + def get_coordinate_system( + self, name: str, path: str | None = None + ) -> CoordinateSystem | None: + """ + Retrieve a coordinate system by name and optional path. + + Parameters + ---------- + name: str + The name of the coordinate system to retrieve. + path: str | None + Optional path to disambiguate coordinate systems with the same name. If None, will return the first match with the given name. + + Returns + ------- + CoordinateSystem or None + The matching CoordinateSystem object, or None if no match is found. + """ + if path is None: + # coordinate system can only be in top-level + possible_coordinate_systems: Sequence[CoordinateSystem] = ( + self.coordinate_systems or [] + ) + + return next( + (cs for cs in possible_coordinate_systems if cs.name == name), None + ) + + possible_coordinate_systems = [] + for group in self.images: + if group == path: + img = self.images[group] + for cs in img.metadata.coordinateSystems: + if cs.name == name: + return cs + return None + + def _build_graph(self): + self._graph = tnd.graph.TransformGraph() + # Add scene-level transformations (empty context = root level) + for tf in self.coordinate_transformations: + if tf.type == "sequence": + source_cs = self.get_coordinate_system(tf.input.name, tf.input.path) + target_cs = self.get_coordinate_system(tf.output.name, tf.output.path) + tnd_transform = self._ozmp_tf_to_tnd( + tf, + zarr_context="", + source_cs=source_cs, + target_cs=target_cs, + ).simplify() + else: + tnd_transform = self._ozmp_tf_to_tnd( + tf, zarr_context="", source_cs=None, target_cs=None + ) + self._graph.add_transform(tnd_transform) + + # check if input/output are defined + subgroups = [] + if tf.input.path is not None: + subgroups.append(tf.input.path) + if tf.output.path is not None: + subgroups.append(tf.output.path) + + for subgroup in subgroups: + img = self.images.get(subgroup) + if img is None: + # Image not found in scene - skip or warn + continue + if img.metadata.coordinateTransformations: + for img_tf in img.metadata.coordinateTransformations: + ind_transform = self._ozmp_tf_to_tnd( + img_tf, + zarr_context=subgroup, + source_cs=None, + target_cs=None, + ) + self._graph.add_transform(ind_transform) + + def to_ome_zarr(self, store: StoreLike, overwrite: bool = False): + """ + Write scene to OME-Zarr format. + + Parameters + ---------- + store: StoreLike + A zarr-compatible storage backend (e.g., directory path, in-memory store, etc.) + overwrite: bool + If True, overwrite all images in the store with the current state of the scene. + If False, only write new images that haven't been written before. Existing images in the store will be left unchanged. + + """ + import shutil + + import tqdm + + from ome_zarr.utils import _recursive_pop_nones + + if overwrite and os.path.exists(str(store)): + # Clear the store if it already exists and we're not doing incremental writes + shutil.rmtree(str(store)) + + # Open or create zarr group + mode = "w" if overwrite else "a" + zarr_group = zarr.open(store, mode=mode) + + # Create a subgroup for each image using its path key + for img_path, img in tqdm.tqdm(self.images.items(), desc="Writing images"): + # Skip if already written (incremental mode) + if not overwrite and img_path in zarr_group: + continue + + # Write the image + subgroup = zarr_group.create_group(img_path, overwrite=overwrite) + img.to_ome_zarr(subgroup, overwrite=True, version="0.6") + + for disp_path, disp_img in (self.coordinates_displacements or {}).items(): + # Skip if already written (incremental mode) + if not overwrite and disp_path in zarr_group: + continue + + # Write the displacement image + subgroup = zarr_group.create_group( + f"coordinateTransformations/{disp_path}", overwrite=overwrite + ) + disp_img.to_ome_zarr(subgroup, overwrite=True, version="0.6") + + # Always update scene metadata + metadata_dict = self.metadata.model_dump() + metadata_dict = _recursive_pop_nones(metadata_dict) + + zarr_group.attrs["ome"] = {"scene": metadata_dict, "version": "0.6.dev4"} + + @classmethod + def from_ome_zarr(cls, store: StoreLike): + """ + Load an existing scene from OME-Zarr format. + + Args: + path: Path to the OME-Zarr scene + + Returns: + NgffScene instance with images and metadata loaded from disk + """ + from ome_zarr_models.v06.scene import BaseSceneAttrs + + # Handle both StoreLike (string, dict, etc.) and zarr.Group objects + if isinstance(store, zarr.Group): + zarr_group = store + else: + zarr_group = zarr.open(store, mode="r") + + # load coordinateTransformations array data, if it exists + if "coordinateTransformations" in zarr_group: + coordinates_displacements = {} + for disp_path in zarr_group["coordinateTransformations"].group_keys(): + disp_group = zarr_group["coordinateTransformations"][disp_path] + disp_img = cast( + OMEZarrMultiscale, OMEZarrMultiscale.from_ome_zarr(disp_group) + ) + coordinates_displacements[disp_path] = disp_img + else: + coordinates_displacements = None + + # Load scene metadata + scene_metadata = BaseSceneAttrs.model_validate(zarr_group.attrs.get("ome", {})) + transformations = scene_metadata.scene.coordinateTransformations + coordinate_systems = scene_metadata.scene.coordinateSystems + + # Load all image subgroups, keyed by their zarr path + images = {} + for tf in transformations: + if hasattr(tf, "input"): + path = tf.input.path + if path is not None and path in zarr_group: + img_group = zarr_group[path] + img = cast( + OMEZarrMultiscale, OMEZarrMultiscale.from_ome_zarr(img_group) + ) + images[path] = img + elif path is not None and path not in zarr_group: + raise ValueError( + f"Image specified in metadata at '{path}' not found in zarr group." + ) + if hasattr(tf, "output"): + path = tf.output.path + if path is not None and path in zarr_group: + img_group = zarr_group[path] + img = cast( + OMEZarrMultiscale, OMEZarrMultiscale.from_ome_zarr(img_group) + ) + images[path] = img + elif path is not None and path not in zarr_group: + raise ValueError( + f"Image specified in metadata at '{path}' not found in zarr group." + ) + + scene = OMEZarrScene( + images=images, + coordinate_transformations=transformations, + coordinate_systems=coordinate_systems, + coordinates_displacements=coordinates_displacements, + ) + + return scene + + def __setattr__(self, name: str, value: Any) -> None: + if name == "coordinate_transformations": + # Update metadata when coordinate transformations are set + parsed_transforms = self._parse_transforms(value) + super().__setattr__(name, parsed_transforms) + # Only update metadata if it exists (not during initial construction) + if hasattr(self, "metadata") and self.metadata is not None: + self.metadata = self.metadata.model_copy( + update={"coordinateTransformations": parsed_transforms} + ) + + elif name == "coordinate_systems": + # Update metadata when coordinate systems are set + parsed_coordinate_systems = self._parse_coordinate_systems(value) + super().__setattr__(name, parsed_coordinate_systems) + # Only update metadata if it exists (not during initial construction) + if hasattr(self, "metadata") and self.metadata is not None: + self.metadata = self.metadata.model_copy( + update={"coordinateSystems": parsed_coordinate_systems} + ) + + else: + # Default behavior for all other attributes + super().__setattr__(name, value) + + @staticmethod + def _parse_transforms( + transforms: Sequence[AnyTransform] | list[dict[str, Any]], + ) -> tuple[AnyTransform, ...]: + """ + Helper method to parse a sequence of coordinate transformations that may be provided as either + AnyTransform instances or dictionaries. + This ensures that all transformations are stored as AnyTransform objects in the scene metadata. + """ + tf_adapter = TypeAdapter(AnyTransform) + parsed_transforms = [] + + for tf in transforms: + if isinstance(tf, dict): + parsed_transforms.append(tf_adapter.validate_python(tf)) + else: + parsed_transforms.append(tf) + + return tuple(parsed_transforms) + + @staticmethod + def _parse_coordinate_systems( + coordinate_systems: ( + Sequence[CoordinateSystem] | Sequence[dict[str, Any]] | None + ), + ) -> tuple[CoordinateSystem, ...] | None: + """ + Helper method to parse a sequence of coordinate systems that may be provided as either + CoordinateSystem instances or dictionaries. + This ensures that all coordinate systems are stored as CoordinateSystem objects in the scene metadata. + If coordinate_systems is None, it will be returned as None. + """ + if coordinate_systems is None: + return None + + parsed_coordinate_systems = [] + for cs in coordinate_systems: + if isinstance(cs, dict): + parsed_coordinate_systems.append(CoordinateSystem.model_validate(cs)) + elif isinstance(cs, CoordinateSystem): + parsed_coordinate_systems.append(cs) + + return tuple(parsed_coordinate_systems) + + def _ozmp_tf_to_tnd( + self, + transform: AnyTransform, + zarr_context: str = "", + source_cs: CoordinateSystem | None = None, + target_cs: CoordinateSystem | None = None, + ) -> tnd.base.Transform: + """ + Convert an OME-Zarr coordinate transformation to a transformnd Transform object. + This is a placeholder function and will need to be implemented based on the specific types of transformations you expect to encounter in OME-Zarr metadata. + """ + import numpy as np + + if transform.input is not None: + input_path = ( + transform.input.path if transform.input.path is not None else "" + ) + output_path = ( + transform.output.path if transform.output.path is not None else "" + ) + + # zarr_context prepends path with relative path from root + # to keep track of global location of coordinate systems in the zarr store + if zarr_context != "" and input_path != "": + input_path = f"{zarr_context}/{input_path}" + elif zarr_context != "": + input_path = zarr_context + + if zarr_context != "" and output_path != "": + output_path = f"{zarr_context}/{output_path}" + elif zarr_context != "": + output_path = zarr_context + + spaces = tnd.Spaces( + f"{input_path}:{transform.input.name}", + f"{output_path}:{transform.output.name}", + ) + else: + spaces = tnd.Spaces(None, None) + + tnd_transform = None + # Example for an affine transformation (this will depend on the actual structure of AnyTransform) + if transform.type == "affine": + aff = np.asarray(transform.affine) + if aff.shape[0] == aff.shape[1]: + tnd_transform = tnd.transforms.Affine( + transform.affine, + spaces=spaces, + ) + else: + aff = np.eye(max(aff.shape)) + aff[: aff.shape[0], : aff.shape[1]] = aff + tnd_transform = tnd.transforms.Affine(aff, spaces=spaces) + + elif transform.type == "displacements": + path_to_dfield = transform.path if transform.path is not None else "" + if zarr_context != "" and path_to_dfield != "": + path_to_dfield = f"{zarr_context}/{path_to_dfield}" + + if self.coordinates_displacements is not None: + dfield = self.coordinates_displacements.get( + path_to_dfield.split("/")[-1] + ) + if dfield is not None: + if dfield.images[0].scale is None: + raise ValueError( + f"Displacement field at {path_to_dfield} is missing scale information." + ) + tnd_transform = tnd.transforms.Displacements( + dfield.images[0].data, + index_transform=tnd.transforms.Scale( + list(dfield.images[0].scale.values())[1:] + ), + vector_axis=0, + spaces=spaces, + ) + elif transform.type == "mapAxis": + tnd_transform = tnd.transforms.MapAxis( + list(transform.mapAxis), + spaces=spaces, + ) + + elif transform.type == "projectAxis": + tnd_transform = tnd.transforms.ProjectAxis( + created=transform.createdOutputs, + dropped=transform.droppedInputs, + spaces=spaces, + source_ndim=len(source_cs.axes) if source_cs is not None else None, + target_ndim=len(target_cs.axes) if target_cs is not None else None, + ) + + elif transform.type == "scale": + tnd_transform = tnd.transforms.Scale(transform.scale, spaces=spaces) + + elif transform.type == "translation": + tnd_transform = tnd.transforms.Translate( + transform.translation, spaces=spaces + ) + + elif transform.type == "rotation": + tnd_transform = tnd.transforms.Affine.from_linear_map( + transform.rotation, spaces=spaces + ) + + elif transform.type == "byDimension": + sub_transformations = transform.transformations + tnd_sub_transforms = [ + tnd.transforms.by_dimension.SubTransform( + transform=self._ozmp_tf_to_tnd(sub_tf.transformation), + input_axes=sub_tf.input_axes, + output_axes=sub_tf.output_axes, + ) + for sub_tf in sub_transformations + ] + tnd_transform = tnd.transforms.ByDimension( + subtransforms=tnd_sub_transforms, + fill_identity=0, + spaces=spaces, + ) + elif transform.type == "sequence": + sub_transformations = transform.transformations + tnd_sub_transforms = [ + self._ozmp_tf_to_tnd(sub_tf, zarr_context, source_cs, target_cs) + for sub_tf in sub_transformations + ] + tnd_transform = tnd.base.TransformSequence( + tnd_sub_transforms, + spaces=spaces, + ) + + return tnd_transform diff --git a/ome_zarr/writer.py b/ome_zarr/writer.py index aa3833ce..23489461 100644 --- a/ome_zarr/writer.py +++ b/ome_zarr/writer.py @@ -4,7 +4,7 @@ import warnings from collections.abc import Sequence from pathlib import Path -from typing import Any, TypeAlias +from typing import Any import dask.array as da import numpy as np @@ -19,10 +19,9 @@ LOGGER = logging.getLogger("ome_zarr.writer") -ListOfArrayLike = list[da.Array] | list[np.ndarray] -ArrayLike: TypeAlias = da.Array | np.ndarray - -AxesType = str | list[str] | list[dict[str, str]] | None +type ListOfArrayLike = list[da.Array] | list[np.ndarray] +type ArrayLike = da.Array | np.ndarray +type AxesType = str | list[str] | list[dict[str, str]] | None SPATIAL_DIMS = ("x", "y", "z") diff --git a/pyproject.toml b/pyproject.toml index 5df1ad4c..549fca1a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -26,8 +26,10 @@ dependencies = [ "scikit-image>=0.19.0", "toolz", "rangehttpserver", - "ome-zarr-models==1.8.0rc0", + "transformnd>=0.6.0", + "ome-zarr-models==1.8.0rc1", "Deprecated", + "tqdm", ] classifiers = [ "Development Status :: 4 - Beta", diff --git a/tests/test_scene.py b/tests/test_scene.py new file mode 100644 index 00000000..960b3039 --- /dev/null +++ b/tests/test_scene.py @@ -0,0 +1,361 @@ +import numpy as np +import pytest +import zarr + +from ome_zarr import OMEZarrImage, OMEZarrMultiscale, OMEZarrScene + +TRANSFORMS = [ + {"type": "scale", "scale": [1.0, 1.0]}, + {"type": "translation", "translation": [0.0, 0.0]}, + {"type": "rotation", "rotation": [[0.0, -1.0], [1.0, 0.0]]}, + {"type": "affine", "affine": [[1.0, 0.0, 0.0], [0.0, 1.0, 0.0]]}, + {"type": "mapAxis", "mapAxis": [1, 0]}, +] + + +@pytest.fixture +def test_data_dir(tmp_path): + """Create a temporary directory with zarr v3 group for testing.""" + path = tmp_path / "data" / "v3" + root_v3 = zarr.open_group(path, mode="w", zarr_format=3) + root_v3.create_group("test") + return path + + +def create_data(shape, dtype=np.uint8, mean_val=10): + """Create dummy testing data of defined shape and type, + with a given mean value.""" + rng = np.random.default_rng(0) + return rng.poisson(mean_val, size=shape).astype(dtype) + + +@pytest.mark.parametrize("transform", TRANSFORMS) +def test_create_scene_without_coordinate_systems(test_data_dir, transform): + """ + Create a scene with two images and a single coordinate transformation + between them. The data is saved and loaded back in the test. + """ + shape = (64, 64) + img_a = OMEZarrImage( + data=create_data(shape), + name="imageA", + axes=["y", "x"], + scale={"y": 1.0, "x": 1.0}, + ) + + img_b = OMEZarrImage( + data=create_data(shape), + name="imageB", + axes=["y", "x"], + scale={"y": 1.0, "x": 1.0}, + ) + + img_a_ms = OMEZarrMultiscale(image=img_a) + img_b_ms = OMEZarrMultiscale(image=img_b) + + # avoid leaking transform mutations into other tests + transform = transform.copy() + transform["input"] = {"name": "physical", "path": "imageA"} + transform["output"] = {"name": "physical", "path": "imageB"} + + scene = OMEZarrScene( + images=[img_a_ms, img_b_ms], + coordinate_transformations=[transform], + ) + + scene.to_ome_zarr("test_scene.zarr", overwrite=True) + + # check that the graph is created correctly + assert scene._graph is not None + + # check that the graph has the correct number of nodes + # (aka coordinate systems) + assert len(scene._graph.graph.nodes) == 2 + + # traverse graph + tf = scene._graph.get_sequence(f"{img_a.name}:physical", f"{img_b.name}:physical") + + # check that the transform graph can be traversed (i.e. transform is not None) + assert tf is not None + + # write to disk and read back + scene.to_ome_zarr(str(test_data_dir / "test_scene.zarr"), overwrite=True) + scene_read = OMEZarrScene.from_ome_zarr(str(test_data_dir / "test_scene.zarr")) + + # check that the graph is created correctly on read + assert scene_read._graph is not None + assert len(scene_read._graph.graph.nodes) == 2 + + # open the zarr group and check the metadata + # and check that the correct metadata fields are present in the store + zarr_group = zarr.open_group(str(test_data_dir / "test_scene.zarr"), mode="r") + assert "ome" in zarr_group.attrs + ome_metadata = zarr_group.attrs["ome"] + assert "scene" in ome_metadata + assert "version" in ome_metadata and ome_metadata["version"] == "0.6.dev4" + + # check transforms + assert "coordinateTransformations" in ome_metadata["scene"] + assert len(ome_metadata["scene"]["coordinateTransformations"]) == 1 + + transform_md = ome_metadata["scene"]["coordinateTransformations"][0] + + # make sure that the loaded transform is the same as the original + assert transform_md == transform + + +@pytest.mark.parametrize("transform", TRANSFORMS) +def test_create_scene_with_coordinate_systems(test_data_dir, transform): + """ + Create a scene with two images and three coordinate transformations + between them. The data is saved and loaded back in the test. + """ + shape = (64, 64) + img_a = OMEZarrImage( + data=create_data(shape), + name="imageA", + axes=["y", "x"], + scale={"y": 1.0, "x": 1.0}, + ) + + img_b = OMEZarrImage( + data=create_data(shape), + name="imageB", + axes=["y", "x"], + scale={"y": 1.0, "x": 1.0}, + ) + + img_a_ms = OMEZarrMultiscale(image=img_a) + img_b_ms = OMEZarrMultiscale(image=img_b) + + world1_cs = { + "name": "world", + "axes": [ax.model_dump() for ax in img_a_ms.metadata.coordinateSystems[0].axes], + } + world2_cs = { + "name": "world2", + "axes": [ax.model_dump() for ax in img_b_ms.metadata.coordinateSystems[0].axes], + } + + transform1 = transform.copy() + transform1["input"] = {"name": "physical", "path": "imageA"} + transform1["output"] = {"name": "world"} + + transform2 = transform.copy() + transform2["input"] = {"name": "world"} + transform2["output"] = {"name": "world2"} + + transform3 = transform.copy() + transform3["input"] = {"name": "world2"} + transform3["output"] = {"name": "physical", "path": "imageB"} + + scene = OMEZarrScene( + images=[img_a_ms, img_b_ms], + coordinate_transformations=[transform1, transform2, transform3], + coordinate_systems=[world1_cs, world2_cs], + ) + + # check that the graph is created correctly + # and has the correct number of nodes (coordinate systems) + assert scene._graph is not None + assert len(scene._graph.graph.nodes) == 4 + + scene.to_ome_zarr(str(test_data_dir / "test_scene_with_cs.zarr"), overwrite=True) + scene_read = OMEZarrScene.from_ome_zarr( + str(test_data_dir / "test_scene_with_cs.zarr") + ) + + # check that the graph is created correctly on read + # and has the correct number of nodes (coordinate systems) + assert scene_read._graph is not None + assert len(scene_read._graph.graph.nodes) == 4 + + # open zarr group and check metadata + zarr_group = zarr.open_group( + str(test_data_dir / "test_scene_with_cs.zarr"), mode="r" + ) + + # make sure that the correct metadata fields are present in the store + assert "ome" in zarr_group.attrs + ome_metadata = zarr_group.attrs["ome"] + assert "scene" in ome_metadata + assert "version" in ome_metadata and ome_metadata["version"] == "0.6.dev4" + assert "coordinateSystems" in ome_metadata["scene"] + assert len(ome_metadata["scene"]["coordinateSystems"]) == 2 + + +def test_appending_scene(test_data_dir): + """ + Create a scene with two images and a single coordinate transformation + between them. The data is saved and loaded back. + We then append a third image to the scene and make sure the graph is updated. + We then save the scene again and ensure that we are writing only what's new + (new data and metadata) + """ + img_a = OMEZarrImage( + data=create_data((64, 64)), + name="imageA", + axes=["y", "x"], + scale={"y": 1.0, "x": 1.0}, + ) + img_b = OMEZarrImage( + data=create_data((64, 64)), + name="imageB", + axes=["y", "x"], + scale={"y": 1.0, "x": 1.0}, + ) + img_c = OMEZarrImage( + data=create_data((64, 64)), + name="imageC", + axes=["y", "x"], + scale={"y": 1.0, "x": 1.0}, + ) + + img_a_ms = OMEZarrMultiscale(image=img_a) + img_b_ms = OMEZarrMultiscale(image=img_b) + img_c_ms = OMEZarrMultiscale(image=img_c) + + world_cs = { + "name": "world", + "axes": [ax.model_dump() for ax in img_a_ms.metadata.coordinateSystems[0].axes], + } + + tf1 = { + "type": "scale", + "scale": [1.0, 1.0], + "input": {"name": "physical", "path": "imageA"}, + "output": {"name": "world"}, + } + + tf2 = { + "type": "scale", + "scale": [1.0, 1.0], + "input": {"name": "world"}, + "output": {"name": "physical", "path": "imageB"}, + } + + tf3 = { + "type": "scale", + "scale": [1.0, 1.0], + "input": {"name": "world"}, + "output": {"name": "physical", "path": "imageC"}, + } + + scene = OMEZarrScene( + images=[img_a_ms, img_b_ms], + coordinate_transformations=[tf1, tf2], + coordinate_systems=[world_cs], + ) + + scene.to_ome_zarr(str(test_data_dir / "test_scene_append.zarr"), overwrite=True) + + # now we load the scene and append a new image to it + scene_read = OMEZarrScene.from_ome_zarr( + str(test_data_dir / "test_scene_append.zarr") + ) + + new_scene = OMEZarrScene( + images=list(scene_read.images.values()) + [img_c_ms], + coordinate_transformations=list(scene_read.coordinate_transformations) + [tf3], + coordinate_systems=[world_cs], + ) + + new_scene.to_ome_zarr( + str(test_data_dir / "test_scene_append.zarr"), overwrite=False + ) + + # check that the graph is built correctly + assert new_scene._graph is not None + assert len(new_scene._graph.graph.nodes) == 4 + + # check that the data is written and not empty + zarr_group = zarr.open_group( + str(test_data_dir / "test_scene_append.zarr"), mode="r" + ) + assert "imageA" in zarr_group and "s0" in zarr_group["imageA"] + assert "imageB" in zarr_group and "s0" in zarr_group["imageB"] + assert "imageC" in zarr_group and "s0" in zarr_group["imageC"] + + # check that the metadata is written and correct + assert "ome" in zarr_group.attrs + ome_metadata = zarr_group.attrs["ome"] + assert "scene" in ome_metadata + scene_metadata = ome_metadata["scene"] + assert "coordinateTransformations" in scene_metadata + assert "coordinateSystems" in scene_metadata + assert len(scene_metadata["coordinateTransformations"]) == 3 + assert len(scene_metadata["coordinateSystems"]) == 1 + + +def test_scene_with_displacements(test_data_dir): + """ + Create a scene with two images and a single coordinate transformation + between them. The data is saved and loaded back in the test. + """ + shape = (64, 64) + img_a = OMEZarrImage( + data=create_data(shape), + name="imageA", + axes=["y", "x"], + scale={"y": 1.0, "x": 1.0}, + ) + + img_b = OMEZarrImage( + data=create_data(shape), + name="imageB", + axes=["y", "x"], + scale={"y": 1.0, "x": 1.0}, + ) + + vector_field = np.zeros((2, 64, 64), dtype=np.float32) + dfield_img = OMEZarrImage( + data=vector_field, + name="displacementField", + axes=["c", "y", "x"], + scale={"y": 1.0, "x": 1.0}, + axes_types={"c": "displacement", "y": "space", "x": "space"}, + ) + + img_a_ms = OMEZarrMultiscale(image=img_a) + img_b_ms = OMEZarrMultiscale(image=img_b) + dfield_img_ms = OMEZarrMultiscale(image=dfield_img) + + transform = { + "type": "displacements", + "input": {"name": "physical", "path": "imageA"}, + "output": {"name": "physical", "path": "imageB"}, + "path": "coordinateTransformations/displacementField", + } + + scene = OMEZarrScene( + images=[img_a_ms, img_b_ms], + coordinate_transformations=[transform], + coordinates_displacements={"displacementField": dfield_img_ms}, + ) + + save_grp = str(test_data_dir / "test_scene_displacement.zarr") + scene.to_ome_zarr(save_grp, overwrite=True) + + # check that all subgroups are there + group = zarr.open_group(save_grp, mode="r") + assert "coordinateTransformations" in group + assert "displacementField" in group["coordinateTransformations"] + assert "imageA" in group + assert "imageB" in group + + # check that the metadata of the displacement field is correct + dfield_attrs = group["coordinateTransformations"]["displacementField"].attrs + assert "ome" in dfield_attrs + assert dfield_attrs["ome"]["version"] == "0.6" + axes_md = dfield_attrs["ome"]["multiscales"][0]["coordinateSystems"][0]["axes"] + assert axes_md[0]["type"] == "displacement" + assert axes_md[0]["discrete"] == True + + # read displacements back in and check that the (meta)data is correct + scene_read = OMEZarrScene.from_ome_zarr(save_grp) + assert "displacementField" in scene_read.coordinates_displacements + + dfield_img = scene_read.coordinates_displacements["displacementField"] + for image in dfield_img.images: + assert image.axes_types["c"] == "displacement" + assert dfield_img.metadata.coordinateSystems[0].axes[0].discrete == True diff --git a/tests/test_writer.py b/tests/test_writer.py index 54811c11..5347f3fd 100644 --- a/tests/test_writer.py +++ b/tests/test_writer.py @@ -70,6 +70,16 @@ def pytest_generate_tests(metafunc): metafunc.parametrize("array_constructor", ARRAY_CONSTRUCTORS) +def _codec_value(value): + """Return the plain value of a codec configuration attribute. + + zarr < 3.3 exposes attributes such as ``BloscCodec.cname`` and + ``BytesCodec.endian`` as (non-str) ``Enum`` members, while zarr >= 3.3 uses + plain strings. + """ + return getattr(value, "value", value) + + def _make_storage_options(fmt, shape, axes): from numcodecs import Blosc from zarr.codecs import ( @@ -178,7 +188,7 @@ def test_additional_transforms(self): ) ms.to_ome_zarr( zarr.open(self.path / "test_transforms.zarr", mode="w"), - version="0.6.dev4", + version="0.6", overwrite=True, ) @@ -197,7 +207,7 @@ def test_additional_transforms(self): ) @pytest.mark.parametrize( - "version", ("0.4", "0.5", "0.6.dev4"), ids=["V04", "V05", "V06"] + "version", ("0.4", "0.5", "0.6"), ids=["V04", "V05", "V06"] ) def test_image_class_versions(self, version): from ome_zarr_models.v06.multiscales import Multiscale as Multiscale_V06 @@ -287,12 +297,16 @@ def test_image_class_bad_args(self): multiscales.to_ome_zarr(self.path / "test_bad_args.zarr", version="0.5.5") @pytest.mark.parametrize("storage_options_list", [True, False]) + @pytest.mark.parametrize( + "version", + ["0.4", "0.5", "0.6"], + ids=["V04", "V05", "V06"], + ) def test_image_class_writer( - self, shape, format_version_all, array_constructor, storage_options_list + self, shape, version, array_constructor, storage_options_list ): - version = format_version_all() - if version.version == "0.5": + if version.startswith(("0.5", "0.6")): grp_path = self.path_v3 / "test" else: grp_path = self.path / "test" @@ -351,7 +365,7 @@ def test_image_class_writer( # write image and labels to disk image_multiscales.to_ome_zarr( group=str(grp_path), - version=version.version, + version=version, storage_options=storage_options, overwrite=True, ) @@ -361,27 +375,32 @@ def test_image_class_writer( node_metadata = out.attrs if "ome" in node_metadata: node_metadata = node_metadata["ome"] + + # multiscales and omero data must be present by default assert "multiscales" in node_metadata + assert "omero" in node_metadata + paths = [d["path"] for d in node_metadata["multiscales"][0]["datasets"]] node_data = [da.from_zarr(grp_path / path) for path in paths] - if version.version in ("0.1", "0.2"): - # v0.1 and v0.2 MUST be 5D - assert node_data[0].ndim == 5 - else: - assert node_data[0].shape == shape - print("node.metadata", node_metadata) # check written coordinatetransormations match relative factors between array sizes for level, nd_array in enumerate(node_data): + ds = node_metadata["multiscales"][0]["datasets"][level] if level == 0: # check first written scale values explicitly match those in TRANSFORMATIONS for d in axes: - assert ( - node_metadata["multiscales"][0]["datasets"][level][ - "coordinateTransformations" - ][0]["scale"][axes.index(d)] - == TRANSFORMATIONS[0][0]["scale"][axes.index(d)] - ) + if version.startswith(("0.4", "0.5")): + tf = ds["coordinateTransformations"][0] + assert ( + tf["scale"][axes.index(d)] + == TRANSFORMATIONS[0][0]["scale"][axes.index(d)] + ) + elif version.startswith("0.6"): + tf = ds["coordinateTransformations"][0]["transformations"][0] + assert ( + tf["scale"][axes.index(d)] + == TRANSFORMATIONS[0][0]["scale"][axes.index(d)] + ) continue # first calculate relative factors between this and previous level @@ -406,9 +425,10 @@ def test_image_class_writer( assert relative_factors["z"] == 1.0 # retrieve written scale factors from metadata and check they match expected - cts = node_metadata["multiscales"][0]["datasets"][level][ - "coordinateTransformations" - ] + if version.startswith(("0.4", "0.5")): + cts = ds["coordinateTransformations"] + elif version.startswith("0.6"): + cts = ds["coordinateTransformations"][0]["transformations"] assert len(cts) == 2 transf = cts[0] assert transf["type"] == "scale" @@ -424,7 +444,7 @@ def test_image_class_writer( # Verify labels data label_group = zarr.open(f"{grp_path}/labels", mode="r") label_group_attrs = label_group.attrs - if version.version == "0.5": + if version == "0.5" or version.startswith("0.6"): label_group_attrs = label_group_attrs["ome"] assert "labels" in label_group_attrs assert labels_name in label_group_attrs["labels"] @@ -434,12 +454,6 @@ def test_image_class_writer( assert labels_name in list(image.labels.keys()) - if version.version == "0.4": - # Validate with ome-zarr-models-py: only supports v0.4 - Models04Image.from_zarr(out) - elif version.version == "0.5": - Models05Image.from_zarr(out) - # verify omero and image-labels metadata if "c" in axes: assert image.omero is not None @@ -2057,7 +2071,7 @@ def test_write_labels_with_storage_options( if level0.compressors: if fmt.version == "0.5": if USE_DASK_ARRAY_KWARGS: - assert level0.compressors[0].cname.name == "zstd" + assert _codec_value(level0.compressors[0].cname) == "zstd" else: assert level0.compressors[0].to_dict()["name"] == "zstd" else: @@ -2066,7 +2080,7 @@ def test_write_labels_with_storage_options( assert level0.compressors[0].clevel == 3 if fmt.version == "0.5" and hasattr(level0, "serializer"): assert ( - level0.metadata.codecs[0].index_codecs[0].endian.name + _codec_value(level0.metadata.codecs[0].index_codecs[0].endian) == "little" ) else: @@ -2250,7 +2264,7 @@ def test_write_multiscale_labels_storage_options( if level.compressors: if fmt.version == "0.5": if USE_DASK_ARRAY_KWARGS: - assert level.compressors[0].cname.name == "zstd" + assert _codec_value(level.compressors[0].cname) == "zstd" else: assert level.compressors[0].to_dict()["name"] == "zstd" else: @@ -2259,7 +2273,9 @@ def test_write_multiscale_labels_storage_options( assert level.compressors[0].clevel == 3 if fmt.version == "0.5" and hasattr(level, "serializer"): assert ( - level.metadata.codecs[0].index_codecs[0].endian.name + _codec_value( + level.metadata.codecs[0].index_codecs[0].endian + ) == "little" ) else: