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

Support other units than nm for datasets #7783

Merged
merged 81 commits into from
Jun 25, 2024
Merged

Support other units than nm for datasets #7783

merged 81 commits into from
Jun 25, 2024

Conversation

MichaelBuessemeyer
Copy link
Contributor

@MichaelBuessemeyer MichaelBuessemeyer commented May 2, 2024

URL of deployed dev instance (used for testing):

  • https://___.webknossos.xyz

Steps to test:

  • See "Features to test" below

TODOs:

  • Never first calculate to nm and then into the desired unit to avoid potential precision loss for very large and very small units.
  • Check Arbitrary View support for this feature 🙈
  • Write tests!
  • Write tests for uncommon units like imperial units or pc
  • Adjust datasource schema validated by the frontend to support all unit. File: frontend/javascripts/types/schemas/datasource.schema.ts
  • Move Parsec to uncommon units
  • Support cm as a format to be formatted to.
    • Now the tests need to be fixed 🥴
  • Import remote dataset should also support the units
    • Backend
    • Frontend (?)
  • How does this interact with meshes? Do meshfiles need unit metadata?
  • Bump backend API version, provide adapter (datasource json format has changed)
  • Write into mesh file docs that the mesh file scale now references the dataset unit. (sneaked it into https://github.com/scalableminds/voxelytics/pull/3491 )
  • PR #7800 introduced a lot of merge conflicts and they need to be resolved.
  • Build auto conversion for huge scales into a better fitting unit.

After this PR / Follow up

Open Questions:

  • Open question: When a length is given in the unit set for the datasource scale, how should this be called in the code? Suggestions:
    • ...InDatasourceUnit
    • ...InDatasetUnit
    • ...InUnit
  • Open question: What to do when an nml is loaded where the unit differs to the dataset?
    • Gets ignored
  • Currently, 1.23456789cm² is formatted to 0.001m² in case a decimal precision of 4 is wanted. Is this how it should be or is this unwanted?
    • This is controlled by the parameter preferShorterDecimals of the formatNumberToUnit function. Here is an example
    1.23456789cm ->  1.23457 cm prefer shorter decimals: false
    1.23456789cm ->  0.00001 km prefer shorter decimals: true
    
    I would prefer to have preferShorterDecimals false as default as it does not cut off that much precision! -> Agreed upon.
  • preferShorterDecimals = false leads to 0.1nm³ getting formatted to 100000000.0 pm³. This is very likely unwanted?!. I could refactor the formatting to always prefer the unit that has fewer digits. But this might require some additional string operations thus making the code potentially slower -> In such a case: measure and look at how frequently the code is called.

Features to test:

  • Adhoc meshing
  • loading precomputed meshes
  • Configuring and saving a unit for a local dataset
  • Configuring and saving a unit for a remote dataset
  • Dataset Info tab (right menu); dataset scale & extent
  • Measure tree length
  • Find the shortest path between nodes
    • Bug Fixed: The vx of "Path length to this Node" is wrong. In the following, the mm seems correct, but the vx is off.
      • The shortest path length between the nodes is 2.0 mm (175.14 vx).
      • The shortest path length between the nodes is 4.1 mm (103.25 vx).
  • 3d viewport interactions: rotation, movement, clicking on meshes/skeletons, context menu, ...
  • Bounding Box tool & Tab
  • Skeleton Tool & Tab & Tree hierarchy view
  • Volume annotations
  • Saving & reloading of annotations
  • Line & Area Measurement Tool & its Tooltip
  • Moving through the dataset (moving the flycam)
  • nml serialization should include the unit (frontend)
  • nml serialization should include the unit (backend)
  • Proofreading mode
  • Download annotation modal
  • AI Jobs Modal (displaying bounding boxes in proper unit)
  • Context Menu
  • api...getViewportData
    • tested via "Click Histogram feature" as this is the only code part using this API function.
  • volume interpolation (uses -> getBoundingBoxForViewport)
  • Segment Stats download

Issues:


(Please delete unneeded items, merge only when none are left open)

MichaelBuessemeyer and others added 3 commits April 30, 2024 17:25
- make keep the base unit internally to nm
- use configured unit for 3d space / voxel space
- WIP: post fix all relevant function with Nm or Vx depending on their unit to make this as explicit as possible
Comment on lines 78 to 93
const datasetExtent = getDatasetExtentInDatasourceUnit(Store.getState().dataset);
console.log(
"CameraController.componentDidMount: getDatasetExtentInDatasourceUnit",
datasetExtent,
);
const diagonalDatasetExtent = Math.sqrt(
datasetExtent.width ** 2 + datasetExtent.height ** 2 + datasetExtent.depth ** 2,
);
this.props.cameras[OrthoViews.TDView].far = diagonalDatasetExtent * 2;
const far = Math.max(8000000, diagonalDatasetExtent * 2);

for (const cam of _.values(this.props.cameras)) {
cam.near = 0;
cam.far = far;
}
// This value is correct
this.props.cameras[OrthoViews.TDView].far = far;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Previously, the value calculated for the far plane was overwritten in lines 103-108 after the 3d viewport was properly initialized. I modified the code to the larger of both values is kept.

And remove datasetScale/voxelSize uniform from shaders as it was unused
@MichaelBuessemeyer
Copy link
Contributor Author

I also renamed datasetScale to voxelSize everywhere in the frontend, as voxelSize makes more sense and is also the term used in the backend and afaik by the wklibs as well

Copy link
Contributor Author

@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.

I just had another look at the backend code and could not locate anything bug/mistake / improvement 🎉

Besides that, here are my pending comments regarding the feedback from @philippotto

frontend/javascripts/libs/format_utils.ts Show resolved Hide resolved
@@ -1027,6 +1027,13 @@ function _getLoadChunksTasks(
// Compute vertex normals to achieve smooth shading
bufferGeometries.forEach((geometry) => geometry.computeVertexNormals());

// Check if the mesh scale is different to the dataset scale and warn in the console to make debugging easier in such a case.
if (!_.isEqual(scale, dataset.dataSource.scale.factor)) {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Precomputed meshes just work fine.

But adhoc meshing seems broken. See my comment / "bug report" below -> good catch

frontend/javascripts/oxalis/view/scalebar.tsx Show resolved Hide resolved
frontend/javascripts/oxalis/view/scalebar.tsx Show resolved Hide resolved
@fm3 fm3 requested a review from philippotto June 12, 2024 09:10
Copy link
Member

@philippotto philippotto left a comment

Choose a reason for hiding this comment

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

awesome 👍 code looks good and it works great, too.

  • Build auto conversion for huge scales into a better fitting unit.

I think, it's not really necessary for this PR. we can advise users to do this manually if problems arise.

@MichaelBuessemeyer
Copy link
Contributor Author

Sorry to ping you again @philippotto. Could you please check the newest changes regarding using the long unit name internally instead of the short one in the frontend?

@MichaelBuessemeyer
Copy link
Contributor Author

Newest backend change LGTM 👍

@philippotto
Copy link
Member

Sorry to ping you again @philippotto. Could you please check the newest changes regarding using the long unit name internally instead of the short one in the frontend?

The changes look good 👍 However, I would suggest to rename UnitShortMap to LongUnitToShortUnitMap or LongToShortUnitMap to make clearer what it contains.

@MichaelBuessemeyer
Copy link
Contributor Author

@fm3 Mergy merge today?

@fm3 fm3 merged commit b6930e5 into master Jun 25, 2024
2 checks passed
@fm3 fm3 deleted the voxel-unit-support branch June 25, 2024 08:09
fm3 added a commit that referenced this pull request Jun 25, 2024
fm3 added a commit that referenced this pull request Jun 25, 2024
fm3 added a commit that referenced this pull request Jun 25, 2024
MichaelBuessemeyer added a commit that referenced this pull request Jun 27, 2024
* Revert "Revert "Support other units than nm for datasets (#7783)" (#7896)"

This reverts commit f874f68.

* always pass short unit version to findBestUnitForFormatting

* in zarr streaming served datasource-properties.json, use old voxel size format

* make typing for UnitDimension / findBestUnitForFormatting more strict

* make type of unit param for adjustUnitToDimension more restrictive

---------

Co-authored-by: Michael Büßemeyer <michael.buessemeyer@student.hpi.de>
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.

Support voxel size in other units than nm
3 participants