Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
cbb334f
feat: Add support/config for InstanceSegmentationMask
aranega Aug 15, 2025
c4aa044
chore: Add new generated code from the new config for
aranega Aug 15, 2025
c4527da
feat: add instance segmentation mask class and instance creation
aranega Sep 4, 2025
2bb7506
chore: remove debug/test code in configuration 10441.yaml
aranega Sep 4, 2025
4a3d320
Merge branch 'main' of github.com:chanzuckerberg/cryoet-data-portal-b…
aranega Sep 12, 2025
bdf0085
feat: remove the instancesegmentation mask from v1, and enhance it for
aranega Sep 12, 2025
5d4bb52
Merge branch 'main' of github.com:chanzuckerberg/cryoet-data-portal-b…
aranega Sep 17, 2025
598e594
feat: add first steps for the InstanceSegmentationMask ingestion
aranega Oct 1, 2025
00a379d
fix: remove bad guard and simplify it
aranega Oct 1, 2025
6dec931
feat: add dedicated shape for the InstanceSegmentationMask
aranega Oct 2, 2025
5d6ac85
fix: remove labels param to convert function of instance seg masks
seankmartin Oct 2, 2025
6101bb2
feat: allow passing seg list into gen and v1 of instance seg mask config
seankmartin Oct 2, 2025
129fde5
feat: Add configuration generation for InstanceSegmentationMask
aranega Oct 7, 2025
0cf3ffe
feat: Remove mask_label for InstanceSegmentationMask
aranega Oct 7, 2025
7eccd55
feat: add label computation and storing before configuration generation
aranega Oct 8, 2025
0968ac4
Merge branch 'main' of github.com:chanzuckerberg/cryoet-data-portal-b…
aranega Oct 17, 2025
a438369
feat: clean schema attribute for the InstanceSegmentationMask
aranega Oct 27, 2025
ac1f46e
feat: add tests for the instance segmentation mask
aranega Oct 27, 2025
0af2440
chore: Updating schema to add InstanceSegmentationMask
aranega Oct 27, 2025
23cd1c5
fix: change is_a property of InstanceSegmentationMask in metadata.yaml
aranega Oct 27, 2025
2233c94
chore: update portal-neuroglancer to v1.7.0
aranega Oct 27, 2025
6f024df
feat: change metadata storing for labels in image-label
aranega Oct 27, 2025
8ec69d7
feat: add tests for instance segmentation mask db ingestion
aranega Oct 27, 2025
6f48941
feat: add a different method for downscaling multi-label segmentation
aranega Oct 28, 2025
6702b85
chore: Add back missing migration script
aranega Oct 28, 2025
37005bb
chore: Update schema to add InstanceSegmentationMask shape
aranega Oct 28, 2025
6bc118c
chore: Fix comment and poetry version
aranega Oct 28, 2025
72a0379
feat: change the container for the image-label metadata
aranega Oct 28, 2025
9ce3ceb
chore: apply old formatter for the migration
aranega Oct 29, 2025
4ac545e
chore: remove InstanceSegmentationMask from v1 schema
aranega Oct 29, 2025
bf96a29
chore: remove lefovers for v1 for InstanceSegmenationMask
aranega Oct 29, 2025
a15f3e6
chore: add back AnnotationInstanceSegmentationFile in metadata.yaml f…
aranega Oct 31, 2025
b31d94c
Merge branch 'main' of github.com:chanzuckerberg/cryoet-data-portal-b…
aranega Oct 31, 2025
1781875
fix: update ingestion tools cert for imod download (#546)
daniel-ji Nov 18, 2025
7b6f6d4
fix: allow oriented mesh scaling to same units as data (#544)
seankmartin Nov 18, 2025
23b2273
feat: NPC-1 ingestion config file. (#548)
uermel Nov 26, 2025
584fc12
feat: add ingestion config (10453) for EMPIAR 12794 - isolated synapt…
daniel-ji Nov 26, 2025
dee5844
fix: neuroglancer config ingestion & db import (fixes staging tomogra…
daniel-ji Nov 26, 2025
d57c026
chore(main): release apiv2 1.14.0 (#549)
czi-github-helper[bot] Nov 26, 2025
06b2f6d
Merge branch 'main' of github.com:chanzuckerberg/cryoet-data-portal-b…
aranega Dec 11, 2025
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
8 changes: 4 additions & 4 deletions .infra/prod/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ stack:
services:
apiv2:
image:
tag: sha-2e0e7d0
tag: sha-3a64fa9
initContainers:
# Install cerbos policies where the cerbos sidecar can grab them.
- name: install-cerbos-policies
image:
repository: 533267185808.dkr.ecr.us-west-2.amazonaws.com/core-platform/cryoet-data-portal-backend/apiv2/apiv2
tag: sha-2e0e7d0
tag: sha-3a64fa9
command: ["cp", "-r", "./cerbos/", "/var/policies/"]
volumeMounts:
- mountPath: /var/policies
Expand All @@ -24,7 +24,7 @@ stack:
- name: run-migrations
image:
repository: 533267185808.dkr.ecr.us-west-2.amazonaws.com/core-platform/cryoet-data-portal-backend/apiv2/apiv2
tag: sha-2e0e7d0
tag: sha-3a64fa9
command: ["alembic", "upgrade", "head"]
resources:
limits:
Expand All @@ -37,7 +37,7 @@ stack:
- name: gen-keypair
image:
repository: 533267185808.dkr.ecr.us-west-2.amazonaws.com/core-platform/cryoet-data-portal-backend/apiv2/apiv2
tag: sha-2e0e7d0
tag: sha-3a64fa9
command: ["bash", "./etc/gen_keys.sh", "/var/keys/"]
volumeMounts:
- mountPath: /var/keys
Expand Down
8 changes: 4 additions & 4 deletions .infra/staging/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ stack:
services:
apiv2:
image:
tag: sha-2e0e7d0
tag: sha-3a64fa9
initContainers:
# Install cerbos policies where the cerbos sidecar can grab them.
- name: install-cerbos-policies
image:
repository: 533267185808.dkr.ecr.us-west-2.amazonaws.com/core-platform/cryoet-data-portal-backend/apiv2/apiv2
tag: sha-2e0e7d0
tag: sha-3a64fa9
command: ["cp", "-r", "./cerbos/", "/var/policies/"]
volumeMounts:
- mountPath: /var/policies
Expand All @@ -24,7 +24,7 @@ stack:
- name: run-migrations
image:
repository: 533267185808.dkr.ecr.us-west-2.amazonaws.com/core-platform/cryoet-data-portal-backend/apiv2/apiv2
tag: sha-2e0e7d0
tag: sha-3a64fa9
command: ["alembic", "upgrade", "head"]
resources:
limits:
Expand All @@ -37,7 +37,7 @@ stack:
- name: gen-keypair
image:
repository: 533267185808.dkr.ecr.us-west-2.amazonaws.com/core-platform/cryoet-data-portal-backend/apiv2/apiv2
tag: sha-2e0e7d0
tag: sha-3a64fa9
command: ["bash", "./etc/gen_keys.sh", "/var/keys/"]
volumeMounts:
- mountPath: /var/keys
Expand Down
2 changes: 1 addition & 1 deletion .release-please-manifest.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
"apiv2": "1.13.2"
"apiv2": "1.14.0"
}
12 changes: 12 additions & 0 deletions apiv2/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,17 @@
# Changelog

## [1.14.0](https://github.com/chanzuckerberg/cryoet-data-portal-backend/compare/apiv2-v1.13.2...apiv2-v1.14.0) (2025-11-26)


### Features

* add ingestion config (10453) for EMPIAR 12794 - isolated synaptic vesicles from mouse brain ([#538](https://github.com/chanzuckerberg/cryoet-data-portal-backend/issues/538)) ([584fc12](https://github.com/chanzuckerberg/cryoet-data-portal-backend/commit/584fc123e1ecbac4557cefbc299231b6f646548b))


### Bug Fixes

* neuroglancer config ingestion & db import (fixes staging tomogram viewer) ([#545](https://github.com/chanzuckerberg/cryoet-data-portal-backend/issues/545)) ([dee5844](https://github.com/chanzuckerberg/cryoet-data-portal-backend/commit/dee584432dc596e94323ea2e79f4e8b582145317))

## [1.13.2](https://github.com/chanzuckerberg/cryoet-data-portal-backend/compare/apiv2-v1.13.1...apiv2-v1.13.2) (2025-10-30)


Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

19 changes: 16 additions & 3 deletions apiv2/db_import/common/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from datetime import datetime
from functools import lru_cache
from pathlib import PurePath
from typing import TYPE_CHECKING, Any
from typing import TYPE_CHECKING, Any, Final

import sqlalchemy as sa
from botocore.exceptions import ClientError
Expand All @@ -20,6 +20,9 @@

logger = logging.getLogger("config")

STAGING_URL: Final[str] = "https://files.cryoet.staging.si.czi.technology"
PROD_URL: Final[str] = "https://files.cryoetdataportal.cziscience.com"


class DBImportConfig:
s3_client: S3Client
Expand All @@ -41,7 +44,7 @@ def __init__(
self.s3fs = s3fs
self.bucket_name = bucket_name
self.s3_prefix = f"s3://{bucket_name}"
self.https_prefix = https_prefix if https_prefix else "https://files.cryoetdataportal.cziscience.com"
self.https_prefix = https_prefix if https_prefix else PROD_URL
self.session = session
self.deposition_map: dict[int, models.Deposition] = {}

Expand Down Expand Up @@ -133,11 +136,21 @@ def load_key_json(self, key: str, is_file_required: bool = True) -> dict[str, An
Loads file matching the key value as json. If file does not exist, will raise error if is_file_required is True
else it will return None.
"""
text = self.load_key_text(key, is_file_required)
if text is None:
return None
return json.loads(text)

def load_key_text(self, key: str, is_file_required: bool = True) -> str | None:
"""
Loads file matching the key value as text. If file does not exist, will raise error if is_file_required is True
else it will return None.
"""
try:
if key.startswith(self.bucket_name):
key = key[len(self.bucket_name) + 1 :]
text = self.s3_client.get_object(Bucket=self.bucket_name, Key=key)
return json.loads(text["Body"].read())
return text["Body"].read().decode("utf-8")
except ClientError as ex:
if ex.response["Error"]["Code"] == "NoSuchKey" and not is_file_required:
logger.warning("NoSuchKey on bucket_name=%s key=%s", self.bucket_name, key)
Expand Down
19 changes: 17 additions & 2 deletions apiv2/db_import/importers/tomogram.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from typing import Any

from database import models
from db_import.common.config import PROD_URL, STAGING_URL
from db_import.common.finders import MetadataFileFinder
from db_import.common.normalize_fields import normalize_fiducial_alignment
from db_import.importers.base import IntegratedDBImporter, ItemDBImporter
Expand Down Expand Up @@ -39,6 +40,16 @@ class TomogramItem(ItemDBImporter):
"is_visualization_default": ["is_visualization_default"],
}

def _update_ng_urls(self, ng_config_text: str) -> str:
"""
A simple function to find and replace all production URLs in the neuroglancer config with the staging URL when in the staging environment.
This is done to ensure that the URLs in the neuroglancer config are correct for the staging environment.
"""
if self.config.https_prefix != STAGING_URL:
return ng_config_text

return ng_config_text.replace(PROD_URL, self.config.https_prefix)

def normalize_to_unknown_str(self, value: str) -> str:
return value.replace(" ", "_") if value else "Unknown"

Expand All @@ -47,9 +58,13 @@ def generate_neuroglancer_data(self, path) -> str | None:
# Handle the case where there is no neuroglancer config file specified which is expected when
# visualization_default is set to False.
return None
config = self.config.load_key_json(path, is_file_required=False)
ng_config_text = self.config.load_key_text(path, is_file_required=False)
if ng_config_text:
ng_config_text = self._update_ng_urls(ng_config_text)
ng_config_json = json.loads(ng_config_text)

# TODO: Log warning
return json.dumps(config, separators=(",", ":")) if config else "{}"
return json.dumps(ng_config_json, separators=(",", ":")) if ng_config_json else "{}"

def load_computed_fields(self):
https_prefix = self.config.https_prefix
Expand Down
2 changes: 1 addition & 1 deletion apiv2/db_import/tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,5 +133,5 @@ def expected_dataset(http_prefix: str) -> dict[str, Any]:
"key_photo_url": f"{http_prefix}/{DATASET_ID}/KeyPhoto/snapshot.png",
"key_photo_thumbnail_url": f"{http_prefix}/{DATASET_ID}/KeyPhoto/thumbnail.png",
"deposition_id": 300,
"file_size": 1374354.0,
"file_size": 1374808.0,
}
18 changes: 18 additions & 0 deletions apiv2/db_import/tests/test_db_annotation_import.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,24 @@ def expected_annotations(http_prefix: str) -> list[dict[str, Any]]:
def expected_annotation_files(http_prefix: str) -> list[dict[str, Any]]:
path = f"{DATASET_ID}/RUN1/Reconstructions/VoxelSpacing12.300/Annotations/"
return [
{
"tomogram_voxel_spacing_id": TOMOGRAM_VOXEL_ID1,
"s3_path": f"s3://test-public-bucket/{path}100-foo-1.0_instancesegmask.mrc",
"https_path": f"{http_prefix}/{path}100-foo-1.0_instancesegmask.mrc",
"source": "community",
"format": "mrc",
"is_visualization_default": False,
"file_size": 0,
},
{
"tomogram_voxel_spacing_id": TOMOGRAM_VOXEL_ID1,
"s3_path": f"s3://test-public-bucket/{path}100-foo-1.0_instancesegmask.zarr",
"https_path": f"{http_prefix}/{path}100-foo-1.0_instancesegmask.zarr",
"source": "community",
"format": "zarr",
"is_visualization_default": False,
"file_size": 0,
},
{
"id": ANNOTATION_FILE_ID,
"tomogram_voxel_spacing_id": TOMOGRAM_VOXEL_ID1,
Expand Down
13 changes: 7 additions & 6 deletions apiv2/graphql_api/schema.graphql

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions apiv2/graphql_api/schema.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions apiv2/graphql_api/types/annotation_shape.py

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions apiv2/graphql_api/types/per_section_parameters.py

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading