Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
142 commits
Select commit Hold shift + click to select a range
525b85d
adapt histogram code in scala to support int8
philippotto Jan 14, 2025
cb645fc
avoid copying bucket data on receive if it's unnecessary
philippotto Jan 14, 2025
b0a464b
use ACE for shader editor and make the editor movable
philippotto Jan 14, 2025
74ee01f
make int8 data layers work
philippotto Jan 14, 2025
7583952
format backend
philippotto Jan 14, 2025
23f3e37
also support int8 segmentations (including rendering of negative values)
philippotto Jan 20, 2025
bafd930
fix ad hoc meshing for negative segment ids
philippotto Jan 20, 2025
01291be
support uint32 color layers
philippotto Jan 21, 2025
d84ad30
fix inverted supportFractionals interpretation in histogram view
philippotto Jan 22, 2025
dac0777
remove unused getRgbaAtIndex implementation
philippotto Jan 23, 2025
ff49df9
make straightforward adaptions for int16
philippotto Jan 23, 2025
93971a9
tmp: don't sanitize layer names and auto-start shader editor
philippotto Jan 23, 2025
36825d2
wip: make dirty adaptions to read int16 data in shader
philippotto Jan 23, 2025
fef329e
wip: support int16 with packingDegree=2
philippotto Jan 23, 2025
fe302a7
refactor
philippotto Jan 23, 2025
f9e141e
more refactoring and fix some dtypes
philippotto Jan 28, 2025
3012352
also allow local puppeteer execution
philippotto Jan 28, 2025
00489d3
add new screenshot tests for dtype datasets
philippotto Jan 28, 2025
fb8cbbb
speed up new dtype screenshot tests by parallelizing them
philippotto Jan 28, 2025
69b08f9
fix typing
philippotto Jan 28, 2025
db7c585
format
philippotto Jan 28, 2025
c3ee927
also support int32 color textures
philippotto Jan 28, 2025
842ee40
fix rendering for very large float values
philippotto Jan 29, 2025
602d8ea
more refactoring in preparation of segmentation tests
philippotto Jan 30, 2025
1b37c7c
tmp: restrict screenshot test on new specs
philippotto Jan 30, 2025
9b79c29
also add segmentation tests
philippotto Jan 30, 2025
398cd8c
handle segmentation ids as uint in shader instead of vec4 (negative i…
philippotto Jan 31, 2025
0ac2eb2
add test capability for special segment ids
philippotto Jan 31, 2025
47ee1f6
tmp: disable olvy
philippotto Feb 3, 2025
447141a
fix all the things :tm:
philippotto Feb 3, 2025
9272d5d
iterate on tests
philippotto Feb 3, 2025
c51e1c1
format
philippotto Feb 3, 2025
efdf88f
clean up and fix typing
philippotto Feb 3, 2025
568ba69
fix int32 segmentation (and add segment test)
philippotto Feb 3, 2025
a78856a
fix uint32 segments
philippotto Feb 3, 2025
c2cba65
don't store 3D viewport in dtype screenshot tests
philippotto Feb 3, 2025
819d221
avoid page reload between specs when the same DS is tested
philippotto Feb 3, 2025
638adcc
add/fix (u)int64 support and add tests
philippotto Feb 4, 2025
ea89f03
clean up
philippotto Feb 4, 2025
aaf0b42
refactor screenshot test parameters
philippotto Feb 4, 2025
6ae05d3
more clean up
philippotto Feb 4, 2025
6ed17f1
more clean up
philippotto Feb 4, 2025
83656a8
refactor getRgbaAtXYIndex and fix the case for multiple data textures…
philippotto Feb 4, 2025
c956398
simplify enabling/disabling name sanitizing for glsl texture names
philippotto Feb 4, 2025
d1a7ee2
remove more obsolete code
philippotto Feb 4, 2025
4703ce3
improve comments
philippotto Feb 4, 2025
55ce5bc
re-enable olvy
philippotto Feb 4, 2025
d6bd518
linting
philippotto Feb 4, 2025
93b14b8
remove channelCountToFormat heuristic in favor of explicitly defining…
philippotto Feb 4, 2025
3846249
Merge branch 'master' of github.com:scalableminds/webknossos into mor…
philippotto Feb 4, 2025
b58a0f3
also set alpha for segmentation layers in tests
philippotto Feb 5, 2025
6038d37
more clean up in tests
philippotto Feb 5, 2025
e7d7ac1
readd noUnusedImports in biome
philippotto Feb 5, 2025
ff5e655
remove unused imports
philippotto Feb 5, 2025
aab24aa
remove unused getChannelCount
philippotto Feb 5, 2025
1772e0a
refactor packingDegree
philippotto Feb 5, 2025
13b70a4
add dtype screenshots
philippotto Feb 6, 2025
c19ef21
fix ad hoc meshing in backend for remaining dtypes
philippotto Feb 6, 2025
23e4ad4
adapt nightly action so that it also triggers the screenshot tests if…
philippotto Feb 6, 2025
66b2e89
disable most ci checks
philippotto Feb 6, 2025
a68960f
skip rest of workflow properly
philippotto Feb 6, 2025
e636be9
rely on manual triggers instead
philippotto Feb 6, 2025
3d74b9a
sanitize subdomain differently than tag name
philippotto Feb 6, 2025
7a61471
undo partial screenshot tests
philippotto Feb 7, 2025
147b17b
Merge branch 'more-dtypes' into trigger-screenshot-nightly
philippotto Feb 7, 2025
1ae16b5
add await to page.close
philippotto Feb 7, 2025
02eefac
fix histograms (necessary for screenshot tests to work)
philippotto Feb 7, 2025
83de554
Merge branch 'more-dtypes' into trigger-screenshot-nightly
philippotto Feb 7, 2025
6efebdc
make td controls invisible in screenshots tests
philippotto Feb 10, 2025
bfa2bb6
move checkBrowserCredentials
philippotto Feb 14, 2025
8720125
properly close puppeteer pages
philippotto Feb 14, 2025
7ca7576
make buttons invisible when screenshotting 3d viewport
philippotto Feb 14, 2025
53d128f
prototype hardcoded permutations
philippotto Feb 14, 2025
31aaea6
add int data types to supported segmentation dtypes
Feb 20, 2025
fdc110b
add default intensity range support to backend
Feb 20, 2025
a580fbd
WIP: Support more dtypes in thumbnail service
Feb 20, 2025
69e0928
fix default intensity ranges
Feb 21, 2025
3d445ce
remove debugging helpers
Feb 21, 2025
b28d31d
fix backend warning
Feb 21, 2025
f1eed3f
also use precomputed frequency permutation and refactor
philippotto Feb 24, 2025
da3cd02
revert default intensity range for int64 and uint64 layers to 0, 255 …
Feb 24, 2025
49b4ef5
refactor the remaining pattern calculation in shader
philippotto Feb 24, 2025
b086ff6
Merge branch 'more-dtypes' of github.com:scalableminds/webknossos int…
philippotto Feb 24, 2025
80573b0
update most screenshots
philippotto Feb 24, 2025
3581a88
temporarily disable ci
philippotto Feb 24, 2025
279a30a
Merge branch 'trigger-screenshot-nightly' into more-dtypes
philippotto Feb 24, 2025
dcff611
fix param in evaluate
philippotto Feb 24, 2025
921bcdb
rename method
Feb 24, 2025
119dffe
Merge branch 'master' of github.com:scalableminds/webknossos into mor…
philippotto Feb 26, 2025
5059071
fix uint24 rendering
philippotto Feb 26, 2025
9e15774
fix uint16
philippotto Feb 26, 2025
aff7318
update screenshots
philippotto Feb 26, 2025
475b4aa
reorder (u)int types
philippotto Feb 27, 2025
9e3515c
incorporate pr feedback
philippotto Feb 27, 2025
8bdda42
DRY some test code
philippotto Feb 27, 2025
ca73a00
move disableLayerNameSanitization to dev flags
philippotto Feb 27, 2025
50dee11
incorporate pr feedback
philippotto Feb 27, 2025
ce2ba3c
linting
philippotto Feb 27, 2025
f33dce8
update screenshots
philippotto Feb 27, 2025
5721415
replace ROI2017_wkw_fallback variant with no-fallback
philippotto Feb 27, 2025
3a7862d
remove unused screenshots
philippotto Feb 27, 2025
9e1aa33
debug output amount of changed pixels
philippotto Feb 27, 2025
2c0dd57
bump allowedThreshold to 0.5% for screenshot tests
philippotto Feb 28, 2025
17c2c74
hopefully fix wrong segment rendering on some hardware
philippotto Feb 28, 2025
58515a3
bump one last time again :tm:
philippotto Feb 28, 2025
6aba8a1
update screenshot
philippotto Feb 28, 2025
282c323
clean up
philippotto Feb 28, 2025
9c62c9b
re-enable ci
philippotto Feb 28, 2025
3db2784
remove superfluous (and incorrect) extrema definition in FindDataServ…
philippotto Feb 28, 2025
77a175b
update changelog
philippotto Feb 28, 2025
9ab7cfc
use correct value range for segmentation layers when dealing with lar…
philippotto Mar 3, 2025
4f5c043
sort imports
philippotto Mar 3, 2025
c0ac4eb
fix linting
philippotto Mar 3, 2025
61e5786
fix comparison
philippotto Mar 3, 2025
e17f1f9
Merge branch 'more-dtypes' of github.com:scalableminds/webknossos int…
Mar 3, 2025
51100c2
fix editing largest segment id
philippotto Mar 4, 2025
4e13245
Merge branch 'more-dtypes' of github.com:scalableminds/webknossos int…
Mar 4, 2025
d103691
fix tests
philippotto Mar 4, 2025
0432134
avoid null in file name and use without_fallback instead
philippotto Mar 5, 2025
3183dd7
Merge branch 'more-dtypes' of github.com:scalableminds/webknossos int…
Mar 5, 2025
0c84bcb
Merge branch 'master' of github.com:scalableminds/webknossos into mor…
Mar 5, 2025
c794c1e
save database access
Mar 5, 2025
9986d92
support additional volume dtypes in proto serialization and deseriali…
Mar 5, 2025
4bbe79e
reduce number of field number duplications for ElementClassProto
Mar 6, 2025
87d80e5
disregard bytes per element in proto serialization and deserialization
Mar 11, 2025
aec67d6
support merging signed volume annotation layers
Mar 11, 2025
99c8986
Merge branch 'master' of github.com:scalableminds/webknossos into mor…
Mar 12, 2025
bee9385
fix toString & equals copy past mistake in new signed Segment Integer…
Mar 12, 2025
f77ed47
format backend
Mar 12, 2025
53aa345
Merge branch 'master' of github.com:scalableminds/webknossos into mor…
philippotto Mar 13, 2025
9bdec04
fix picking and setting negative segment ids
philippotto Mar 13, 2025
d9fd36a
improve logic of warnAboutInvalidSegmentId saga
philippotto Mar 13, 2025
fab128e
fix crash when brushing in int64 DS
philippotto Mar 13, 2025
7d2ceed
fix redundant line in changelog
philippotto Mar 13, 2025
ce900dc
fix endless recursion
philippotto Mar 13, 2025
aa22c3b
Remove compilation errors -> make elementclass fromProto case complete
Mar 18, 2025
8f083e5
catch case unrecognized explicitly in elementclass fromProto
Mar 18, 2025
ba135d1
make ElementClass.toProto return a box with a failure in case of unsu…
Mar 18, 2025
71405dc
format backend
Mar 18, 2025
19dffff
remove elementClassToProto implicit
Mar 18, 2025
7d43ee4
Merge branch 'master' of github.com:scalableminds/webknossos into mor…
philippotto Mar 19, 2025
2fcefaa
Merge branch 'master' into more-dtypes
philippotto Mar 19, 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
32 changes: 22 additions & 10 deletions .github/workflows/nightly.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,23 @@ jobs:
- name: Checkout code
uses: actions/checkout@v3

- name: Process and Log Branch Name
run: |
echo "BRANCH_NAME=${{ github.ref_name }}" >> $GITHUB_ENV
SUBDOMAIN=$(echo "${{ github.ref_name }}" | tr -dc '[:alpha:]' | tr '[:upper:]' '[:lower:]')
TAG_NAME=$(echo "${{ github.ref_name }}" | sed 's/[\/-]/_/g')

echo "SUBDOMAIN=$SUBDOMAIN" >> $GITHUB_ENV
echo "TAG_NAME=$TAG_NAME" >> $GITHUB_ENV

echo "Sanitized branch name: $SUBDOMAIN"
echo "Tag name: $TAG_NAME"

- name: Remove dev-deployment
run: |
curl -X POST \
-H "X-Auth-Token: ${{ secrets.RELEASE_API_TOKEN }}" \
https://kubernetix.scm.io/hooks/remove/webknossos/dev/master?user=CI+%28nightly%29
https://kubernetix.scm.io/hooks/remove/webknossos/dev/${{ env.TAG_NAME }}?user=CI+%28nightly%29

- name: Wait 3 minutes
run: sleep 180
Expand All @@ -27,32 +39,32 @@ jobs:
run: |
curl -X POST \
-H "X-Auth-Token: ${{ secrets.RELEASE_API_TOKEN }}" \
https://kubernetix.scm.io/hooks/install/webknossos/dev/master?user=CI+%28nightly%29
https://kubernetix.scm.io/hooks/install/webknossos/dev/${{ env.TAG_NAME }}?user=CI+%28nightly%29

- uses: actions/setup-node@v4
with:
node-version: 18
node-version: 18

- name: Install dependencies and wait
run: |
corepack enable && yarn install --immutable &
sleep 180 &
wait
corepack enable && yarn install --immutable &
sleep 180 &
wait

- name: Refresh datasets
run: |
curl -X POST --fail https://master.webknossos.xyz/data/triggers/checkInboxBlocking?token=${{ secrets.WK_AUTH_TOKEN }}
curl -X POST --fail https://${{ env.SUBDOMAIN }}.webknossos.xyz/data/triggers/checkInboxBlocking?token=${{ secrets.WK_AUTH_TOKEN }}

- name: Run screenshot tests
run: |
URL=https://master.webknossos.xyz/ \
URL=https://${{ env.SUBDOMAIN }}.webknossos.xyz/ \
timeout 3000 \
yarn test-screenshot
env:
URL: https://master.webknossos.xyz/
URL: https://${{ env.SUBDOMAIN }}.webknossos.xyz/
WK_AUTH_TOKEN: ${{ secrets.WK_AUTH_TOKEN }}
BROWSERSTACK_USERNAME: ${{ secrets.BROWSERSTACK_USERNAME }}
BROWSERSTACK_ACCESS_KEY : ${{ secrets.BROWSERSTACK_ACCESS_KEY }}
BROWSERSTACK_ACCESS_KEY: ${{ secrets.BROWSERSTACK_ACCESS_KEY }}

- name: Upload screenshots as artifact
uses: actions/upload-artifact@v4
Expand Down
2 changes: 2 additions & 0 deletions CHANGELOG.unreleased.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ For upgrade instructions, please check the [migration guide](MIGRATIONS.released
[Commits](https://github.com/scalableminds/webknossos/compare/25.02.1...HEAD)

### Added
- Added support for datasets with the following data types: int8, int16, int32, uint32 (support for color was added, support for segmentation already existed before) and int64 (segmentation only). [#8325](https://github.com/scalableminds/webknossos/pull/8325)
- Added a command palette that allows navigating between pages, switching tools and accessing some user settings via Ctrl+P. [#8447](https://github.com/scalableminds/webknossos/pull/8447/)
- Failed jobs may be retried by super-users. [#8377](https://github.com/scalableminds/webknossos/pull/8377)

Expand All @@ -24,6 +25,7 @@ For upgrade instructions, please check the [migration guide](MIGRATIONS.released
- Fixed a bug that would lock a non-existing mapping to an empty segmentation layer under certain conditions. [#8401](https://github.com/scalableminds/webknossos/pull/8401)
- Fixed the alignment of the button that allows restricting floodfill operations to a bounding box. [#8388](https://github.com/scalableminds/webknossos/pull/8388)
- Fixed rare bug where saving got stuck. [#8409](https://github.com/scalableminds/webknossos/pull/8409)
- Fixed some rendering bugs for float datasets that used a large dynamic range. [#8325](https://github.com/scalableminds/webknossos/pull/8325)
- Fixed a bug where reverting annotations could get stuck if some of its layers had been deleted in the meantime. [#8405](https://github.com/scalableminds/webknossos/pull/8405)
- When removing a segment from the segment list, a corresponding precomputed mesh was not removed automatically. [#8428](https://github.com/scalableminds/webknossos/pull/8428)
- Fixed a bug where newly added remote datasets would always appear in root folder, regardless of actual selected folder. [#8425](https://github.com/scalableminds/webknossos/pull/8425)
Expand Down
2 changes: 1 addition & 1 deletion app/controllers/AnnotationController.scala
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ class AnnotationController @Inject()(
dataset <- datasetDAO.findOne(datasetId) ?~> Messages("dataset.notFound", datasetId) ~> NOT_FOUND
annotation <- annotationService.createExplorationalFor(
request.identity,
dataset._id,
dataset,
request.body
) ?~> "annotation.create.failed"
_ = analyticsService.track(CreateAnnotationEvent(request.identity: User, annotation: Annotation))
Expand Down
10 changes: 6 additions & 4 deletions app/controllers/AnnotationIOController.scala
Original file line number Diff line number Diff line change
Expand Up @@ -327,18 +327,20 @@ class AnnotationIOController @Inject()(
val bbox =
if (volumeTracing.boundingBox.isEmpty) boundingBoxToProto(dataSource.boundingBox)
else volumeTracing.boundingBox
val elementClass = fallbackLayerOpt
.map(layer => elementClassToProto(layer.elementClass))
.getOrElse(elementClassToProto(VolumeTracingDefaults.elementClass))

for {
tracingCanHaveSegmentIndex <- canHaveSegmentIndex(organizationId,
dataset.name,
fallbackLayerOpt.map(_.name),
remoteDataStoreClient)
elementClassProto <- fallbackLayerOpt
.map(layer => ElementClass.toProto(layer.elementClass))
.getOrElse(ElementClass.toProto(VolumeTracingDefaults.elementClass))
.toFox
} yield
volumeTracing.copy(
boundingBox = bbox,
elementClass = elementClass,
elementClass = elementClassProto,
fallbackLayer = fallbackLayerOpt.map(_.name),
largestSegmentId = combineLargestSegmentIdsByPrecedence(volumeTracing.largestSegmentId,
fallbackLayerOpt.map(_.largestSegmentId)),
Expand Down
17 changes: 9 additions & 8 deletions app/models/annotation/AnnotationService.scala
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,9 @@ class AnnotationService @Inject()(
remoteDatastoreClient.hasSegmentIndexFile(datasetOrganizationId, dataSource.id.directoryName, layer.name)
case None => Fox.successful(false)
}
elementClassProto <- ElementClass
.toProto(fallbackLayer.map(layer => layer.elementClass).getOrElse(VolumeTracingDefaults.elementClass))
.toFox
} yield
VolumeTracing(
None,
Expand All @@ -149,8 +152,7 @@ class AnnotationService @Inject()(
dataSource.id.directoryName,
vec3IntToProto(startPosition.getOrElse(dataSource.center)),
vec3DoubleToProto(startRotation.getOrElse(vec3DoubleFromProto(VolumeTracingDefaults.editRotation))),
elementClassToProto(
fallbackLayer.map(layer => layer.elementClass).getOrElse(VolumeTracingDefaults.elementClass)),
elementClassProto,
fallbackLayer.map(_.name),
combineLargestSegmentIdsByPrecedence(fromNml = None, fromFallbackLayer = fallbackLayer.map(_.largestSegmentId)),
0,
Expand Down Expand Up @@ -289,19 +291,18 @@ class AnnotationService @Inject()(
_ <- tracingStoreClient.saveAnnotationProto(annotationId, annotationProto)
} yield newAnnotationLayers

def createExplorationalFor(user: User,
datasetId: ObjectId,
annotationLayerParameters: List[AnnotationLayerParameters])(
def createExplorationalFor(user: User, dataset: Dataset, annotationLayerParameters: List[AnnotationLayerParameters])(
implicit ctx: DBAccessContext,
m: MessagesProvider): Fox[Annotation] =
m: MessagesProvider): Fox[Annotation] = {
val newAnnotationId = ObjectId.generate
val datasetId = dataset._id
for {
dataset <- datasetDAO.findOne(datasetId) ?~> "dataset.noAccessById"
newAnnotationId = ObjectId.generate
annotationLayers <- createLayersForExplorational(dataset, newAnnotationId, annotationLayerParameters) ?~> "annotation.createTracings.failed"
teamId <- selectSuitableTeam(user, dataset) ?~> "annotation.create.forbidden"
annotation = Annotation(newAnnotationId, datasetId, None, teamId, user._id, annotationLayers)
_ <- annotationDAO.insertOne(annotation)
} yield annotation
}

// WARNING: needs to be repeatable, might be called multiple times for an annotation
def finish(annotation: Annotation, user: User, restrictions: AnnotationRestrictions)(
Expand Down
4 changes: 2 additions & 2 deletions app/models/annotation/nml/NmlParser.scala
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import com.scalableminds.util.tools.Fox.box2Fox
import com.scalableminds.util.tools.JsonHelper.bool2Box
import com.scalableminds.webknossos.datastore.SkeletonTracing._
import com.scalableminds.webknossos.datastore.MetadataEntry.MetadataEntryProto
import com.scalableminds.webknossos.datastore.VolumeTracing.VolumeTracing.ElementClassProto
import com.scalableminds.webknossos.datastore.VolumeTracing.{Segment, SegmentGroup, VolumeTracing}
import com.scalableminds.webknossos.datastore.geometry.{
AdditionalAxisProto,
Expand All @@ -19,7 +20,6 @@ import com.scalableminds.webknossos.datastore.geometry.{
Vec3IntProto
}
import com.scalableminds.webknossos.datastore.helpers.{NodeDefaults, ProtoGeometryImplicits, SkeletonTracingDefaults}
import com.scalableminds.webknossos.datastore.models.datasource.ElementClass
import com.scalableminds.webknossos.tracingstore.tracings.ColorGenerator
import com.scalableminds.webknossos.tracingstore.tracings.skeleton.updating.TreeType
import com.scalableminds.webknossos.tracingstore.tracings.skeleton.{MultiComponentTreeSplitter, TreeValidator}
Expand Down Expand Up @@ -75,7 +75,7 @@ class NmlParser @Inject()(datasetDAO: DatasetDAO) extends LazyLogging with Proto
datasetName = dataset.name,
editPosition = nmlParams.editPosition,
editRotation = nmlParams.editRotation,
elementClass = ElementClass.uint32, // Note: this property may be adapted later in adaptPropertiesToFallbackLayer
elementClass = ElementClassProto.uint32, // Note: this property may be adapted later in adaptPropertiesToFallbackLayer
Copy link
Contributor

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Consider dynamic element class assignment instead of hardcoding to uint32.

While changing to ElementClassProto.uint32 is consistent with the import change, the PR objective is to support multiple data types (int8, int16, int32, int64, etc.). Hardcoding to uint32 might limit the flexibility needed for the enhanced data type support.


🏁 Script executed:

#!/bin/bash
# Check if there are any other places where ElementClassProto is used dynamically

# Look for ElementClassProto references
rg -A 5 "ElementClassProto" --type scala

# Check if there is any code that determines element class based on data type
rg -A 10 "elementClass =" --type scala

Length of output: 56119


Action Required: Use Dynamic Element Class Assignment in NmlParser.scala

The current implementation in NmlParser.scala (line 78) still hardcodes elementClass as ElementClassProto.uint32. Given that the PR aims to support multiple data types (e.g., int8, int16, int32, int64, etc.), this reduces flexibility and may cause inconsistencies with other parts of the codebase that derive the element class dynamically.

  • File: app/models/annotation/nml/NmlParser.scala
    Line: 78
    Issue: elementClass is hardcoded instead of being computed based on context (for example, using input parameters or configuration similar to dynamic assignments in VolumeTracing or DataLayer modules).

Please consider refactoring the assignment to derive elementClass dynamically and ensure it aligns with the enhanced data type support objective. Alternatively, add a clear justification if dynamic assignment is to be deferred.

fallbackLayer = v.fallbackLayerName,
largestSegmentId = v.largestSegmentId,
version = 0,
Expand Down
4 changes: 2 additions & 2 deletions frontend/javascripts/admin/admin_rest_api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import * as Utils from "libs/utils";
import window, { location } from "libs/window";
import _ from "lodash";
import messages from "messages";
import type { AnnotationTypeFilterEnum, LOG_LEVELS, Vector2, Vector3 } from "oxalis/constants";
import type { AnnotationTypeFilterEnum, LOG_LEVELS, Vector3 } from "oxalis/constants";
import Constants, { ControlModeEnum, AnnotationStateFilterEnum } from "oxalis/constants";
import type BoundingBox from "oxalis/model/bucket_data_handling/bounding_box";
import {
Expand Down Expand Up @@ -2234,7 +2234,7 @@ export async function getSamMask(
pointY: number; // int, relative to topleft
},
additionalCoordinates: AdditionalCoordinate[],
intensityRange?: Vector2 | null,
intensityRange?: readonly [number, number] | null,
): Promise<Uint8Array> {
const params = new URLSearchParams();
if (intensityRange != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import Toast from "libs/toast";
import { jsonStringify, parseMaybe } from "libs/utils";
import { BoundingBoxInput, Vector3Input } from "libs/vector_input";
import { AllUnits, LongUnitToShortUnitMap, type Vector3 } from "oxalis/constants";
import { getBitDepth } from "oxalis/model/accessors/dataset_accessor";
import { getSupportedValueRangeForElementClass } from "oxalis/model/bucket_data_handling/data_rendering_logic";
import type { BoundingBoxObject, OxalisState } from "oxalis/store";
import * as React from "react";
import { useSelector } from "react-redux";
Expand Down Expand Up @@ -362,7 +362,7 @@ function SimpleLayerForm({
const dataLayers = Form.useWatch(["dataSource", "dataLayers"]);
const category = Form.useWatch(["dataSource", "dataLayers", index, "category"]);
const isSegmentation = category === "segmentation";
const bitDepth = getBitDepth(layer);
const valueRange = getSupportedValueRangeForElementClass(layer.elementClass);

const mayLayerBeRemoved = dataLayers?.length > 1;

Expand Down Expand Up @@ -585,21 +585,23 @@ function SimpleLayerForm({
rules={[
{
validator: (_rule, value) =>
value == null || value === "" || (value > 0 && value < 2 ** bitDepth)
value == null ||
value === "" ||
(value >= valueRange[0] && value <= valueRange[1] && value !== 0)
? Promise.resolve()
: Promise.reject(
new Error(
`The largest segmentation ID must be greater than 0 and smaller than 2^${bitDepth}. You can also leave this field empty, but annotating this layer later will only be possible with manually chosen segment IDs.`,
`The largest segmentation ID must be between ${valueRange[0]} and ${valueRange[1]} and not 0. You can also leave this field empty, but annotating this layer later will only be possible with manually chosen segment IDs.`,
),
),
},
{
warningOnly: true,
validator: (_rule, value) =>
value != null && value === 2 ** bitDepth - 1
value != null && value === valueRange[1]
? Promise.reject(
new Error(
`The largest segmentation ID has already reached the maximum possible value of 2^${bitDepth}-1. Annotations of this dataset cannot create new segments.`,
`The largest segmentation ID has already reached the maximum possible value of ${valueRange[1]}. Annotations of this dataset cannot create new segments.`,
),
)
: Promise.resolve(),
Expand Down
9 changes: 2 additions & 7 deletions frontend/javascripts/libs/UpdatableTexture.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import type { TypedArray } from "oxalis/constants";
import * as THREE from "three";

/* The UpdatableTexture class exposes a way to partially update a texture.
Expand Down Expand Up @@ -75,13 +76,7 @@ class UpdatableTexture extends THREE.Texture {
return this.renderer.properties.get(this).__webglTexture != null;
}

update(
src: Float32Array | Uint8Array | Uint32Array,
x: number,
y: number,
width: number,
height: number,
) {
update(src: TypedArray, x: number, y: number, width: number, height: number) {
if (originalTexSubImage2D == null) {
// See explanation at declaration of originalTexSubImage2D.
originalTexSubImage2D = this.gl.texSubImage2D.bind(this.gl);
Expand Down
9 changes: 1 addition & 8 deletions frontend/javascripts/libs/cuckoo/abstract_cuckoo_table.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,18 +50,12 @@ export abstract class AbstractCuckooTable<K, V, Entry extends [K, V]> {
this._texture = createUpdatableTexture(
textureWidth,
textureWidth,
this.getClass().getTextureChannelCount(),
this.getClass().getTextureType(),
getRenderer(),
this.getClass().getTextureFormat(),
this.getClass().getInternalFormat(),
);

// The internal format has to be set manually, since ThreeJS does not
// derive this value by itself.
// See https://webgl2fundamentals.org/webgl/lessons/webgl-data-textures.html
// for a reference of the internal formats.
this._texture.internalFormat = this.getClass().getInternalFormat();

this.entryCapacity = Math.floor(
(textureWidth ** 2 * this.getClass().getTextureChannelCount()) /
this.getClass().getElementsPerEntry(),
Expand Down Expand Up @@ -96,7 +90,6 @@ export abstract class AbstractCuckooTable<K, V, Entry extends [K, V]> {
// Use 1x1 texture to avoid WebGL warnings.
1,
1,
this.getTextureChannelCount(),
this.getTextureType(),
getRenderer(),
this.getTextureFormat(),
Expand Down
24 changes: 18 additions & 6 deletions frontend/javascripts/libs/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -881,9 +881,11 @@ export function waitForElementWithId(elementId: string): Promise<any> {
}

export function convertDecToBase256(num: number): Vector4 {
const sign = Math.sign(num);

const divMod = (n: number) => [Math.floor(n / 256), n % 256];

let tmp = num;
let tmp = Math.abs(num);

let r: number, g: number, b: number, a: number;
[tmp, r] = divMod(tmp);
Expand All @@ -895,11 +897,13 @@ export function convertDecToBase256(num: number): Vector4 {
[tmp, a] = divMod(tmp);

// Little endian
return [r, g, b, a];
return map4((el) => sign * el, [r, g, b, a]);
}

export function castForArrayType(uncastNumber: number, data: TypedArray): number | bigint {
return data instanceof BigUint64Array ? BigInt(uncastNumber) : uncastNumber;
return data instanceof BigUint64Array || data instanceof BigInt64Array
? BigInt(uncastNumber)
: uncastNumber;
}

export function convertNumberTo64Bit(num: number | bigint | null): [Vector4, Vector4] {
Expand All @@ -915,12 +919,20 @@ export function convertNumberTo64BitTuple(num: number | bigint | null): [number,
if (num == null || Number.isNaN(num)) {
return [0, 0];
}

let sign: number | null;
if (typeof num === "bigint") {
sign = num < 0n ? -1 : 1;
} else {
sign = Math.sign(num);
}

// Cast to BigInt as bit-wise operations only work with 32 bits,
// even though Number uses 53 bits.
const bigNum = BigInt(num);
const bigNum = BigInt(sign) * BigInt(num);

const bigNumLow = Number((2n ** 32n - 1n) & bigNum);
const bigNumHigh = Number(bigNum >> 32n);
const bigNumLow = sign * Number((2n ** 32n - 1n) & bigNum);
const bigNumHigh = sign * Number(bigNum >> 32n);

return [bigNumHigh, bigNumLow];
}
Expand Down
11 changes: 6 additions & 5 deletions frontend/javascripts/messages.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -177,9 +177,12 @@ instead. Only enable this option if you understand its effect. All layers will n
</span>
),
"tracing.copy_cell_id": "Hit CTRL + I to copy the currently hovered segment id",
"tracing.segment_id_out_of_bounds": _.template(
"Cannot create a segment id larger than the segment layers maximum value of <%- maxSegmentId %>.",
),
"tracing.segment_id_out_of_bounds": (
requestedId: number,
validRange: readonly [number, number],
) =>
`Cannot create a segment with id=${requestedId} because it is not between ${validRange[0]} and ${validRange[1]}.`,

"tracing.copy_maybe_mapped_cell_id":
"Hit CTRL + I to copy the currently hovered segment id. Press CTRL + ALT + I if you want to copy the mapped id.",
"tracing.no_more_branchpoints": "No more branchpoints",
Expand Down Expand Up @@ -365,8 +368,6 @@ instead. Only enable this option if you understand its effect. All layers will n
`The layer "${layerName}" was defined as ${elementClass}. This format is not officially supported. Please convert the layer to a supported format.`,
"dataset.unsupported_segmentation_class_uint24":
"The segmentation layer was defined as uint24. This format is not supported for segmentations. Please convert the layer to a supported format.",
"dataset.unsupported_segmentation_class_int64":
"The segmentation layer was defined as int64. This format is not supported for segmentations. Please convert the layer to the unsigned uint64 format.",
"dataset.is_scratch":
"This dataset location is marked as 'scratch' and meant for testing only. Please move this dataset to a permanent storage location and reimport it.",
"dataset.z1_downsampling_hint":
Expand Down
1 change: 0 additions & 1 deletion frontend/javascripts/oxalis/api/cross_origin_api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,6 @@ function CrossOriginApi() {
// biome-ignore lint/correctness/useExhaustiveDependencies: Rerun each time window.webknossos changes.
useEffect(() => {
if (window.webknossos && window.parent) {
// @ts-expect-error ts-migrate(2339) FIXME: Property 'webknossos' does not exist on type 'Wind... Remove this comment to see the full error message
window.webknossos.apiReady().then(() => {
window.parent.postMessage(
{
Expand Down
Loading