Skip to content

Conversation

fm3
Copy link
Member

@fm3 fm3 commented Jul 31, 2025

Editable mapping (aka supervoxel proofreading) annotations can now be downloaded and the edited edges are included in a zarr3-based format. Note that re-upload is not yet implemented.

Format description:

  • The <volume> tag in the NML now mentions the editedMappingBaseMappingName for editableMapping annotations.
  • It also mentions editedMappingEdgesLocation, which points to a zipfile
  • That zipfile contains a zarr3 group with two (chunked but not sharded) arrays:
    • edges (uint64 2D array): src and dst segment id of the edited edges in editing order
    • edgeIsAddition (bool 1D array): for each edge, encodes whether this edge was an addition (to perform a merge) or a removal (to perform a split)

Steps to test:

  • Perform some supervoxel proofreading actions in a new annotation
  • Download that annotation, unpack the zip, check that the format conforms to what was described above
  • in python, read the arrays with something like tensorstore.open("file:///myAnnotation/editedMappingEdges_Volume/edgeIsAddition").result().read().result() and check that the result looks correct (ordering of the two arrays should match and be in editing order)
  • Make sure that normal non-editable-mapping annotations can still be downloaded + reuploaded

TODOs:

  • Fetch edited edges
    • respect requested version
    • iron out reverts
  • Encode to zarr
  • Zip
  • Include in volume download zip
  • mention in NML
  • ensure ordering is correct
  • ensure bool semantic is correct
  • cleanup

Issues:


  • Added changelog entry (create a $PR_NUMBER.md file in unreleased_changes or use ./tools/create-changelog-entry.py)
  • Removed dev-only changes like prints and application.conf edits
  • Considered common edge cases

Copy link
Contributor

coderabbitai bot commented Jul 31, 2025

📝 Walkthrough

Walkthrough

This change introduces the ability to export editable mapping (proofreading) annotations, including the edited edges, as part of annotation downloads. It adds logic to serialize edited mapping edges into a zipped Zarr3 format, updates relevant data models and controllers, and adds a new HTTP endpoint for retrieving the zipped edited edges. Supporting utilities and serialization methods are also updated or introduced.

Changes

Cohort / File(s) Change Summary
Controller & Download Logic
app/controllers/AnnotationIOController.scala, app/models/annotation/WKRemoteTracingStoreClient.scala, app/models/annotation/nml/NmlWriter.scala
Adds support for including edited mapping edges in annotation downloads and NML export; updates method signatures and logic to fetch and serialize these edges.
Data Model Updates
webknossos-datastore/app/com/scalableminds/webknossos/datastore/models/annotation/AnnotationLayer.scala
Extends FetchedAnnotationLayer with optional fields for edited mapping edges and base mapping name; adds naming utility and updates factory method.
Zarr3 Serialization & Utilities
webknossos-datastore/app/com/scalableminds/webknossos/datastore/datareaders/zarr3/EmptyZarr3GroupHeader.scala, webknossos-datastore/app/com/scalableminds/webknossos/datastore/datareaders/zarr3/Zarr3ArrayHeader.scala, util/src/main/scala/com/scalableminds/util/io/FileIO.scala, util/src/main/scala/com/scalableminds/util/tools/JsonHelper.scala
Introduces new Zarr3 group header class, enhances array header serialization for booleans, adds JSON serialization utility for streams, and removes unused file streaming code.
Tracingstore: Controller, Service, and Routing
webknossos-tracingstore/app/com/scalableminds/webknossos/tracingstore/controllers/EditableMappingController.scala, webknossos-tracingstore/app/com/scalableminds/webknossos/tracingstore/tracings/editablemapping/EditableMappingIOService.scala, webknossos-tracingstore/app/com/scalableminds/webknossos/tracingstore/tracings/editablemapping/EditableMappingService.scala, webknossos-tracingstore/conf/tracingstore.latest.routes
Adds a new endpoint and service for exporting edited mapping edges as zipped Zarr3; implements logic to extract, serialize, and serve these edges; updates routing.
Zarr3 Stream Sink Update
webknossos-tracingstore/app/com/scalableminds/webknossos/tracingstore/tracings/volume/Zarr3BucketStreamSink.scala
Refactors to use new JSON serialization utility for stream creation, simplifying code.
Documentation/Changelog
unreleased_changes/8816.md
Documents the new capability to download editable mapping annotations in Zarr3 format.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~35 minutes

Assessment against linked issues

Objective Addressed Explanation
Export format for Editable Mappings/Proofreading annotations should include info to reconstruct edited mapping (inserted/removed edges) and encode as zarr (#8805)
Flatten/compact update actions as described (#8805)
Provide a download route for zipped edited edges (#8805)
Reupload functionality for edited annotations (#8805) Reupload/construction of new update actions from uploaded zarr is not implemented in this change.

Assessment against linked issues: Out-of-scope changes

Code Change Explanation
Removal of NamedFileStream and createTempFile from util/src/main/scala/com/scalableminds/util/io/FileIO.scala These utility removals are not directly related to the editable mapping export/export format objectives.
Refactor to use NamedFunctionStream.fromJsonSerializable in webknossos-tracingstore/app/com/scalableminds/webknossos/tracingstore/tracings/volume/Zarr3BucketStreamSink.scala This is a code simplification unrelated to the editable mapping export objective.

Possibly related issues

Suggested labels

enhancement

Suggested reviewers

  • MichaelBuessemeyer

Poem

🐇
In burrows deep, I zipped the proof,
Edges mapped, in Zarr3's roof.
Merges, splits—now neatly packed,
For download, every edit tracked.
The warren's work, a tidy feat,
Annotation export—oh, what a treat!
🗂️✨

Note

⚡️ Unit Test Generation is now available in beta!

Learn more here, or try it out under "Finishing Touches" below.


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0f0c335 and 77f9475.

📒 Files selected for processing (2)
  • webknossos-tracingstore/app/com/scalableminds/webknossos/tracingstore/tracings/editablemapping/EditableMappingIOService.scala (1 hunks)
  • webknossos-tracingstore/app/com/scalableminds/webknossos/tracingstore/tracings/volume/VolumeTracingService.scala (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • webknossos-tracingstore/app/com/scalableminds/webknossos/tracingstore/tracings/volume/VolumeTracingService.scala
🚧 Files skipped from review as they are similar to previous changes (1)
  • webknossos-tracingstore/app/com/scalableminds/webknossos/tracingstore/tracings/editablemapping/EditableMappingIOService.scala
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: backend-tests
  • GitHub Check: frontend-tests
  • GitHub Check: build-smoketest-push
✨ Finishing Touches
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch export-edited-mapping-edges

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai generate unit tests to generate unit tests for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@fm3 fm3 self-assigned this Aug 5, 2025
@fm3 fm3 marked this pull request as ready for review August 5, 2025 10:54
@fm3 fm3 changed the title WIP: Export edited edges from editable mapping Export edited edges from editable mapping Aug 5, 2025
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (1)
app/models/annotation/WKRemoteTracingStoreClient.scala (1)

283-290: Consider more specific error handling for JSON parsing.

The JSON extraction at line 289 could fail silently if the baseMappingName field is missing. Consider adding a more descriptive error message.

-          .flatMap(jsObj => JsonHelper.as[String](jsObj \ "baseMappingName").toFox)
+          .flatMap(jsObj => JsonHelper.as[String](jsObj \ "baseMappingName").toFox ?~> "editableMapping.baseMappingName.missing")
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 96d6b45 and 0f0c335.

📒 Files selected for processing (14)
  • app/controllers/AnnotationIOController.scala (1 hunks)
  • app/models/annotation/WKRemoteTracingStoreClient.scala (5 hunks)
  • app/models/annotation/nml/NmlWriter.scala (1 hunks)
  • unreleased_changes/8816.md (1 hunks)
  • util/src/main/scala/com/scalableminds/util/io/FileIO.scala (2 hunks)
  • util/src/main/scala/com/scalableminds/util/tools/JsonHelper.scala (0 hunks)
  • webknossos-datastore/app/com/scalableminds/webknossos/datastore/datareaders/zarr3/EmptyZarr3GroupHeader.scala (1 hunks)
  • webknossos-datastore/app/com/scalableminds/webknossos/datastore/datareaders/zarr3/Zarr3ArrayHeader.scala (3 hunks)
  • webknossos-datastore/app/com/scalableminds/webknossos/datastore/models/annotation/AnnotationLayer.scala (3 hunks)
  • webknossos-tracingstore/app/com/scalableminds/webknossos/tracingstore/controllers/EditableMappingController.scala (3 hunks)
  • webknossos-tracingstore/app/com/scalableminds/webknossos/tracingstore/tracings/editablemapping/EditableMappingIOService.scala (1 hunks)
  • webknossos-tracingstore/app/com/scalableminds/webknossos/tracingstore/tracings/editablemapping/EditableMappingService.scala (4 hunks)
  • webknossos-tracingstore/app/com/scalableminds/webknossos/tracingstore/tracings/volume/Zarr3BucketStreamSink.scala (1 hunks)
  • webknossos-tracingstore/conf/tracingstore.latest.routes (1 hunks)
💤 Files with no reviewable changes (1)
  • util/src/main/scala/com/scalableminds/util/tools/JsonHelper.scala
🧰 Additional context used
🧠 Learnings (7)
📚 Learning: in webknossos scala codebase, when querying database tables with slick, explicit column listing in s...
Learnt from: frcroth
PR: scalableminds/webknossos#8821
File: app/models/dataset/Dataset.scala:864-866
Timestamp: 2025-08-04T11:49:30.012Z
Learning: In WebKnossos Scala codebase, when querying database tables with Slick, explicit column listing in SELECT statements is preferred over SELECT * to ensure columns are returned in the exact order expected by case class mappings. This prevents parsing failures when the physical column order in the production database doesn't match the schema definition order.

Applied to files:

  • webknossos-tracingstore/app/com/scalableminds/webknossos/tracingstore/tracings/volume/Zarr3BucketStreamSink.scala
  • webknossos-tracingstore/app/com/scalableminds/webknossos/tracingstore/tracings/editablemapping/EditableMappingService.scala
📚 Learning: in the `updatemags` method of datasetmagsdao (scala), the code handles different dataset types disti...
Learnt from: frcroth
PR: scalableminds/webknossos#8609
File: app/models/dataset/Dataset.scala:753-775
Timestamp: 2025-05-12T13:07:29.637Z
Learning: In the `updateMags` method of DatasetMagsDAO (Scala), the code handles different dataset types distinctly:
1. Non-WKW datasets have `magsOpt` populated and use the first branch which includes axisOrder, channelIndex, and credentialId.
2. WKW datasets will have `wkwResolutionsOpt` populated and use the second branch which includes cubeLength.
3. The final branch is a fallback for legacy data.
This ensures appropriate fields are populated for each dataset type.

Applied to files:

  • webknossos-tracingstore/app/com/scalableminds/webknossos/tracingstore/tracings/volume/Zarr3BucketStreamSink.scala
  • webknossos-datastore/app/com/scalableminds/webknossos/datastore/datareaders/zarr3/Zarr3ArrayHeader.scala
📚 Learning: in `frontend/javascripts/oxalis/model/sagas/proofread_saga.ts`, when calling `getmaginfo`, the use o...
Learnt from: dieknolle3333
PR: scalableminds/webknossos#8168
File: frontend/javascripts/oxalis/model/sagas/proofread_saga.ts:1039-1039
Timestamp: 2024-11-22T17:18:04.217Z
Learning: In `frontend/javascripts/oxalis/model/sagas/proofread_saga.ts`, when calling `getMagInfo`, the use of `volumeTracingLayer.resolutions` is intentional and should not be changed to `volumeTracingLayer.mags`.

Applied to files:

  • app/models/annotation/nml/NmlWriter.scala
📚 Learning: in the webknossos codebase, classes extending `foximplicits` have access to an implicit conversion f...
Learnt from: frcroth
PR: scalableminds/webknossos#8236
File: webknossos-datastore/app/com/scalableminds/webknossos/datastore/services/mesh/MeshFileService.scala:170-173
Timestamp: 2025-04-23T08:51:57.756Z
Learning: In the webknossos codebase, classes extending `FoxImplicits` have access to an implicit conversion from `Option[A]` to `Fox[A]`, where `None` is converted to an empty Fox that fails gracefully in for-comprehensions.

Applied to files:

  • webknossos-tracingstore/app/com/scalableminds/webknossos/tracingstore/tracings/editablemapping/EditableMappingService.scala
  • app/models/annotation/WKRemoteTracingStoreClient.scala
  • util/src/main/scala/com/scalableminds/util/io/FileIO.scala
📚 Learning: in scala's for-comprehension with fox (future-like type), the `<-` operator ensures sequential execu...
Learnt from: MichaelBuessemeyer
PR: scalableminds/webknossos#8352
File: app/models/organization/CreditTransactionService.scala:0-0
Timestamp: 2025-01-27T12:06:42.865Z
Learning: In Scala's for-comprehension with Fox (Future-like type), the `<-` operator ensures sequential execution. If any step fails, the entire chain short-circuits and returns early, preventing subsequent operations from executing. This makes it safe to perform validation checks before database operations.

Applied to files:

  • webknossos-tracingstore/app/com/scalableminds/webknossos/tracingstore/tracings/editablemapping/EditableMappingService.scala
  • app/models/annotation/WKRemoteTracingStoreClient.scala
  • util/src/main/scala/com/scalableminds/util/io/FileIO.scala
📚 Learning: in scala for-comprehensions with the fox error handling monad, `fox.frombool()` expressions should u...
Learnt from: frcroth
PR: scalableminds/webknossos#8236
File: webknossos-datastore/app/com/scalableminds/webknossos/datastore/services/mesh/NeuroglancerPrecomputedMeshFileService.scala:161-166
Timestamp: 2025-04-28T14:18:04.368Z
Learning: In Scala for-comprehensions with the Fox error handling monad, `Fox.fromBool()` expressions should use the `<-` binding operator instead of the `=` assignment operator to properly propagate error conditions. Using `=` will cause validation failures to be silently ignored.

Applied to files:

  • app/models/annotation/WKRemoteTracingStoreClient.scala
📚 Learning: in `dataseterrorloggingservice.scala`, prefer using `textutils.stacktraceasstring(exception)` when l...
Learnt from: frcroth
PR: scalableminds/webknossos#8202
File: webknossos-datastore/app/com/scalableminds/webknossos/datastore/services/DatasetErrorLoggingService.scala:68-72
Timestamp: 2024-11-25T10:02:03.702Z
Learning: In `DatasetErrorLoggingService.scala`, prefer using `TextUtils.stackTraceAsString(exception)` when logging exceptions instead of passing the exception directly to `logger.error`.

Applied to files:

  • app/models/annotation/WKRemoteTracingStoreClient.scala
🔇 Additional comments (23)
webknossos-datastore/app/com/scalableminds/webknossos/datastore/datareaders/zarr3/EmptyZarr3GroupHeader.scala (2)

5-8: LGTM! Well-structured Zarr3 group header implementation.

The case class correctly defines the required Zarr3 group header fields with appropriate default values. The zarr_format field is correctly fixed to 3 for Zarr v3 compliance, and node_type is appropriately set to "group".


10-14: LGTM! Standard JSON serialization implementation.

The companion object follows standard Play JSON patterns with the implicit formatter and provides a sensible filename constant for the Zarr JSON file.

util/src/main/scala/com/scalableminds/util/io/FileIO.scala (2)

8-8: LGTM! Appropriate JSON imports added.

The Play JSON imports are correctly added to support the new JSON serialization functionality.


34-40: LGTM! Well-implemented JSON serialization utility.

The fromJsonSerializable method is well-designed with:

  • Proper use of the Writes typeclass for type-safe JSON serialization
  • Sensible default for pretty printing
  • Clean delegation to existing fromString method
  • Good method signature with implicit parameters
webknossos-datastore/app/com/scalableminds/webknossos/datastore/models/annotation/AnnotationLayer.scala (3)

76-77: LGTM! Well-designed optional fields for edited mapping support.

The new optional fields follow existing patterns and maintain backward compatibility:

  • editedMappingEdgesOpt mirrors the existing volumeDataOpt pattern
  • baseMappingNameOpt provides necessary metadata
  • Both use Option types with None defaults for backward compatibility

87-91: LGTM! Consistent filename generation method.

The editedMappingEdgesZipName method correctly follows the same pattern as the existing volumeDataZipName method, ensuring consistency in filename generation logic and handling of index/single scenarios.


98-112: LGTM! Factory method correctly updated.

The fromAnnotationLayer method is properly updated to support the new optional parameters while maintaining backward compatibility through default None values. The parameters are correctly passed through to the constructor.

unreleased_changes/8816.md (1)

1-2: LGTM! Clear and informative changelog entry.

The changelog entry accurately describes the new editable mapping download functionality and appropriately notes the current limitation that re-upload is not yet implemented. The mention of the zarr3-based format provides useful technical context.

webknossos-tracingstore/conf/tracingstore.latest.routes (1)

41-41: LGTM! Well-structured route addition.

The new route is properly placed in the Editable Mappings section and follows established conventions:

  • Uses appropriate GET method for download functionality
  • Parameter types (String, Option[Long]) match expected controller signature
  • Route path clearly indicates its purpose (editedEdgesZip)
app/controllers/AnnotationIOController.scala (1)

505-509: LGTM! Clean integration of edited mapping edges.

The code correctly follows the existing pattern for adding volume data to the ZIP archive. Setting the compression level to BEST_SPEED is appropriate for maintaining consistency with the volume data handling above.

webknossos-tracingstore/app/com/scalableminds/webknossos/tracingstore/tracings/volume/Zarr3BucketStreamSink.scala (2)

63-63: LGTM! Good refactoring to centralize JSON serialization.

Using fromJsonSerializable instead of manual JSON serialization improves code maintainability and consistency across the codebase.


65-67: LGTM! Consistent application of the serialization refactoring.

The change maintains the same functionality while using the centralized JSON serialization approach.

app/models/annotation/nml/NmlWriter.scala (2)

283-283: LGTM! Updated to use the correct accessor method.

The change from hasEditableMapping.getOrElse(false) to getHasEditableMapping aligns with the protobuf accessor pattern and is more concise.


291-296: LGTM! Clean integration of edited mapping edges metadata.

The conditional writing of editedMappingEdgesLocation and editedMappingBaseMappingName attributes follows the established pattern and correctly integrates the new editable mapping features into the NML export format.

webknossos-datastore/app/com/scalableminds/webknossos/datastore/datareaders/zarr3/Zarr3ArrayHeader.scala (3)

31-31: LGTM! Clear documentation of boolean handling limitations.

The updated comment clearly explains the constraints around boolean dataset handling, which is helpful for future developers.


239-241: LGTM! Correct boolean fill_value handling.

The logic correctly handles boolean data types by converting the string representation ("true") to a proper JSON boolean value. This ensures proper zarr3 format compliance.


259-263: LGTM! Improved JSON object construction.

The conditional inclusion of optional fields (storage_transformers and dimension_names) is a good practice that avoids polluting the JSON with undefined fields while maintaining clean, readable code.

webknossos-tracingstore/app/com/scalableminds/webknossos/tracingstore/controllers/EditableMappingController.scala (3)

13-13: LGTM! Appropriate import for the new functionality.

The import correctly adds the EditableMappingIOService needed for the new edited edges export feature.


30-31: LGTM! Proper dependency injection setup.

The dependency injection for EditableMappingIOService follows the established pattern in the controller constructor.


150-168: LGTM! Well-implemented controller action for edited edges export.

The editedEdgesZip method correctly follows established patterns in the controller:

  • Proper access token validation
  • Standard error handling with Fox
  • Logical flow: validate access → fetch data → process → return response
  • Appropriate use of the injected EditableMappingIOService

The implementation looks solid and integrates well with the existing codebase.

app/models/annotation/WKRemoteTracingStoreClient.scala (1)

277-282: LGTM! Good use of conditional data fetching.

The implementation correctly fetches edited mapping edges only when the tracing has editable mapping, avoiding unnecessary network calls.

webknossos-tracingstore/app/com/scalableminds/webknossos/tracingstore/tracings/editablemapping/EditableMappingIOService.scala (1)

39-103: Well-structured zarr3 serialization implementation.

The implementation correctly handles:

  • Chunking for memory efficiency
  • Proper zarr3 header construction with appropriate metadata
  • Efficient compression using Blosc
  • Clear separation of concerns between edge data and boolean flags
webknossos-tracingstore/app/com/scalableminds/webknossos/tracingstore/tracings/editablemapping/EditableMappingService.scala (1)

540-575: Well-implemented edge extraction logic.

The implementation correctly:

  • Fetches and processes update groups with proper version handling
  • Uses ironOutReverts to handle reverted actions appropriately
  • Distinguishes between split (false) and merge (true) operations
  • Filters actions by the specific tracing ID
  • Handles optional segment IDs with position fallback

@fm3 fm3 requested a review from MichaelBuessemeyer August 5, 2025 11:17
@fm3 fm3 changed the title Export edited edges from editable mapping Export edited edges from editable mapping (proofreading annotation) Aug 6, 2025
Copy link
Contributor

@MichaelBuessemeyer MichaelBuessemeyer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome thanks for this new feature.

I left a few minor comments below.

Regarding testing:

  • When downloading as wkw, the edited edges are still exported as zarr. This is a little unexpected but I'd say fine for now. Alternatively, wkw download could omit the edited edges
    Besides that, everything is awesome :)

Side note: To open the zarr array I needed to do smth like this. Not sure why though:

tensorstore.open({
    'driver': 'zarr3',
    'kvstore': {
        'driver': 'file',
        'path': '<path>/editedMappingEdges_Volume/edges'
    }
}).result().read().result()

Comment on lines +127 to +144
private lazy val compressorConfiguration =
BloscCodecConfiguration(
BloscCompressor.defaultCname,
BloscCompressor.defaultCLevel,
StringCompressionSetting(BloscCodecConfiguration.shuffleSettingFromInt(BloscCompressor.defaultShuffle)),
Some(BloscCompressor.defaultTypesize),
BloscCompressor.defaultBlocksize
)

private lazy val compressor =
new BloscCompressor(
Map(
BloscCompressor.keyCname -> StringCompressionSetting(BloscCompressor.defaultCname),
BloscCompressor.keyClevel -> IntCompressionSetting(BloscCompressor.defaultCLevel),
BloscCompressor.keyShuffle -> IntCompressionSetting(BloscCompressor.defaultShuffle),
BloscCompressor.keyBlocksize -> IntCompressionSetting(BloscCompressor.defaultBlocksize),
BloscCompressor.keyTypesize -> IntCompressionSetting(BloscCompressor.defaultTypesize)
))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So the configs in compressorConfiguration and compressor always need to be kept in sync? Isn't is possible to just create the compressor and get its configuration? We coded this ourselves. So this might be something for a future refactoring 🤔?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point, I wrote #8842 for that

@fm3 fm3 requested a review from MichaelBuessemeyer August 7, 2025 10:59
Copy link
Contributor

@MichaelBuessemeyer MichaelBuessemeyer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome, thanks for all the replies

@fm3 fm3 merged commit d8e3194 into master Aug 7, 2025
5 checks passed
@fm3 fm3 deleted the export-edited-mapping-edges branch August 7, 2025 11:13
fm3 added a commit that referenced this pull request Aug 11, 2025
It’s always empty in this case anyway, so I’d say it makes more sense to
omit it.

Also let’s interpret skipVolumeData so that the proofreading zip is also
omitted

Follow-up for #8816
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Export format for Editable Mappings/Proofreading annotations

2 participants