Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[python] Update Scene create method in the Python API #3356

Merged
merged 2 commits into from
Nov 27, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 30 additions & 11 deletions apis/python/src/tiledbsoma/_scene.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
Implementation of a SOMA Scene
"""

import warnings
from typing import Any, List, Optional, Sequence, Tuple, Type, TypeVar, Union

import somacore
Expand All @@ -17,9 +18,13 @@
from typing_extensions import Self

from . import _funcs, _tdb_handles
from . import pytiledbsoma as clib
from ._collection import CollectionBase
from ._constants import SOMA_COORDINATE_SPACE_METADATA_KEY
from ._exception import SOMAError
from ._constants import (
SOMA_COORDINATE_SPACE_METADATA_KEY,
SPATIAL_DISCLAIMER,
)
from ._exception import SOMAError, map_exception_for_create
from ._geometry_dataframe import GeometryDataFrame
from ._multiscale_image import MultiscaleImage
from ._point_cloud_dataframe import PointCloudDataFrame
Expand All @@ -32,6 +37,7 @@
)
from ._types import OpenTimestamp
from .options import SOMATileDBContext
from .options._soma_tiledb_context import _validate_soma_tiledb_context

_spatial_element = Union[GeometryDataFrame, MultiscaleImage, PointCloudDataFrame]

Expand Down Expand Up @@ -97,16 +103,29 @@
Lifecycle:
Experimental.
"""
if coordinate_space is not None:
raise NotImplementedError(
"Setting the coordinate space on create is not yet implemented."
warnings.warn(SPATIAL_DISCLAIMER)

context = _validate_soma_tiledb_context(context)
try:
timestamp_ms = context._open_timestamp_ms(tiledb_timestamp)
clib.SOMAScene.create(
ctx=context.native_context,
uri=uri,
timestamp=(0, timestamp_ms),
)
return super().create(
uri=uri,
platform_config=platform_config,
context=context,
tiledb_timestamp=tiledb_timestamp,
)
handle = cls._wrapper_type.open(uri, "w", context, tiledb_timestamp)
if coordinate_space is not None:
if not isinstance(coordinate_space, CoordinateSpace):
coordinate_space = CoordinateSpace.from_axis_names(coordinate_space)
handle.meta[SOMA_COORDINATE_SPACE_METADATA_KEY] = (
coordinate_space_to_json(coordinate_space)
)
return cls(
handle,
_dont_call_this_use_create_or_open_instead="tiledbsoma-internal-code",
)
except SOMAError as e:
raise map_exception_for_create(e, uri) from None

Check warning on line 128 in apis/python/src/tiledbsoma/_scene.py

View check run for this annotation

Codecov / codecov/patch

apis/python/src/tiledbsoma/_scene.py#L127-L128

Added lines #L127 - L128 were not covered by tests

def __init__(
self,
Expand Down
18 changes: 16 additions & 2 deletions apis/python/src/tiledbsoma/soma_collection.cc
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,22 @@ void load_soma_collection(py::module& m) {
py::class_<SOMAMeasurement, SOMACollection, SOMAGroup, SOMAObject>(
m, "SOMAMeasurement");

py::class_<SOMAScene, SOMACollection, SOMAGroup, SOMAObject>(
m, "SOMAScene");
py::class_<SOMAScene, SOMACollection, SOMAGroup, SOMAObject>(m, "SOMAScene")
.def_static(
"create",
[](std::shared_ptr<SOMAContext> ctx,
std::string_view uri,
std::optional<TimestampRange> timestamp) {
try {
SOMAScene::create(uri, ctx, timestamp);
} catch (const std::exception& e) {
TPY_ERROR_LOC(e.what());
}
},
py::kw_only(),
"ctx"_a,
"uri"_a,
"timestamp"_a = py::none());

py::class_<SOMAMultiscaleImage, SOMACollection, SOMAGroup, SOMAObject>(
m, "SOMAMultiscaleImage");
Expand Down
34 changes: 33 additions & 1 deletion apis/python/tests/test_scene.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,39 @@ def test_measurement_with_var_scene(tmp_path):
assert soma.DataFrame.exists(obs_scene_uri)


def test_scene_coord_space(tmp_path):
def test_scene_coord_space_at_create(tmp_path):
uri = tmp_path.as_uri()

coord_space = soma.CoordinateSpace(
[
soma.Axis(name="x"),
soma.Axis(name="y"),
]
)
coord_space_json = """
[
{"name": "x", "unit": null},
{"name": "y", "unit": null}
]
"""

with soma.Scene.create(uri, coordinate_space=("x", "y")) as scene:

# Reserved metadata key should not be settable?
# with pytest.raises(soma.SOMAError):
# scene.metadata["soma_coordinate_space"] = coord_space_json

scene.coordinate_space = coord_space
assert scene.coordinate_space == coord_space
assert json.loads(scene.metadata["soma_coordinate_space"]) == json.loads(
coord_space_json
)

with soma.Scene.open(uri) as scene:
assert scene.coordinate_space == coord_space


def test_scene_coord_space_after_create(tmp_path):
uri = tmp_path.as_uri()

coord_space = soma.CoordinateSpace(
Expand Down
27 changes: 3 additions & 24 deletions libtiledbsoma/src/soma/soma_scene.cc
Original file line number Diff line number Diff line change
Expand Up @@ -46,30 +46,9 @@ void SOMAScene::create(
std::optional<TimestampRange> timestamp) {
try {
std::filesystem::path scene_uri(uri);

SOMAGroup::create(ctx, scene_uri.string(), "SOMAScene", timestamp);
SOMACollection::create((scene_uri / "img").string(), ctx, timestamp);
SOMACollection::create((scene_uri / "obsl").string(), ctx, timestamp);
SOMACollection::create((scene_uri / "varl").string(), ctx, timestamp);

auto name = std::string(std::filesystem::path(uri).filename());
auto group = SOMAGroup::open(
OpenMode::write, scene_uri.string(), ctx, name, timestamp);
group->set(
(scene_uri / "img").string(),
URIType::absolute,
"img",
"SOMACollection");
group->set(
(scene_uri / "obsl").string(),
URIType::absolute,
"obsl",
"SOMACollection");
group->set(
(scene_uri / "varl").string(),
URIType::absolute,
"varl",
"SOMAColelction");
auto group = SOMAGroup::create(
ctx, scene_uri.string(), "SOMAScene", timestamp);
// TODO: Set extra metadata.
jp-dark marked this conversation as resolved.
Show resolved Hide resolved
group->close();
} catch (TileDBError& e) {
throw TileDBSOMAError(e.what());
Expand Down
2 changes: 1 addition & 1 deletion libtiledbsoma/src/soma/soma_scene.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ class SOMAScene : public SOMACollection {
*
* @param uri URI to create the SOMAScene
* @param schema TileDB ArraySchema
* @param platform_config Optional config parameter dictionary
* @param timestamp Optional pair indicating timestamp start and end
*/
static void create(
std::string_view uri,
Expand Down
Loading