Skip to content

Commit 0eaf018

Browse files
authored
Merge branch 'master' into delete-workflow-reports
2 parents 9f65900 + 159f868 commit 0eaf018

File tree

7 files changed

+52
-37
lines changed

7 files changed

+52
-37
lines changed

CHANGELOG.unreleased.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ For upgrade instructions, please check the [migration guide](MIGRATIONS.released
2626
- Admins can now see and cancel all jobs. The owner of the job is shown in the job list. [#8112](https://github.com/scalableminds/webknossos/pull/8112)
2727
- Migrated nightly screenshot tests from CircleCI to GitHub actions. [#8134](https://github.com/scalableminds/webknossos/pull/8134)
2828
- Migrated nightly screenshot tests for wk.org from CircleCI to GitHub actions. [#8135](https://github.com/scalableminds/webknossos/pull/8135)
29+
- Thumbnails for datasets now use the selected mapping from the view configuration if available. [#8157](https://github.com/scalableminds/webknossos/pull/8157)
2930

3031
### Fixed
3132
- Fixed a bug during dataset upload in case the configured `datastore.baseFolder` is an absolute path. [#8098](https://github.com/scalableminds/webknossos/pull/8098) [#8103](https://github.com/scalableminds/webknossos/pull/8103)
@@ -36,6 +37,8 @@ For upgrade instructions, please check the [migration guide](MIGRATIONS.released
3637
- Fixed sorting of mags in outbound zarr streaming. [#8125](https://github.com/scalableminds/webknossos/pull/8125)
3738
- Fixed a bug where you could not create annotations for public datasets of other organizations. [#8107](https://github.com/scalableminds/webknossos/pull/8107)
3839
- Users without edit permissions to a dataset can no longer delete sharing tokens via the API. [#8083](https://github.com/scalableminds/webknossos/issues/8083)
40+
- Fixed downloading task annotations of teams you are not in, when accessing directly via URI. [#8155](https://github.com/scalableminds/webknossos/pull/8155)
41+
- Deleting a bounding box is now possible independently of a visible segmentation layer. [#8164](https://github.com/scalableminds/webknossos/pull/8164)
3942

4043
### Removed
4144

DEV_INSTALL.md

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ arch -x86_64 /bin/zsh
4444
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
4545

4646
# Install git, node.js, postgres, sbt, gfind, gsed, draco
47-
brew install openjdk draco openssl git node postgresql sbt findutils coreutils gnu-sed redis yarn c-blosc brotli wget
47+
brew install openjdk draco openssl git node postgresql sbt findutils coreutils gnu-sed redis c-blosc brotli wget
4848

4949
# Set env variables for openjdk and openssl
5050
# You probably want to add these lines manually to avoid conflicts in your zshrc
@@ -84,12 +84,8 @@ source ~/.bashrc
8484
nvm install 18
8585
nvm use 18
8686

87-
# Adding repositories for yarn
88-
curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add -
89-
echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list
90-
9187
sudo apt update
92-
sudo apt install -y git postgresql postgresql-client unzip zip yarn redis-server build-essential libblosc1 libbrotli1 libdraco-dev cmake
88+
sudo apt install -y git postgresql postgresql-client unzip zip redis-server build-essential libblosc1 libbrotli1 libdraco-dev cmake
9389

9490
# Install sdkman, java, scala and sbt
9591
curl -s "https://get.sdkman.io" | bash
@@ -132,8 +128,10 @@ On older Ubuntu distributions: Please make sure to have the correct versions of
132128
### node.js & yarn
133129

134130
* Install node from [http://nodejs.org/download/](http://nodejs.org/download/)
135-
* node version **16 to 18 is required**
136-
* Install yarn package manager: `npm install -g yarn`
131+
* node version **18 is required**
132+
* Use `corepack` to install `yarn`
133+
* `corepack enable`&& `yarn install`
134+
137135

138136
## Run locally
139137

app/controllers/AnnotationIOController.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -457,7 +457,7 @@ class AnnotationIOController @Inject()(
457457
tracingStoreClient.getSkeletonTracing(skeletonAnnotationLayer, skeletonVersion)
458458
} ?~> "annotation.download.fetchSkeletonLayer.failed"
459459
user <- userService.findOneCached(annotation._user)(GlobalAccessContext) ?~> "annotation.download.findUser.failed"
460-
taskOpt <- Fox.runOptional(annotation._task)(taskDAO.findOne)
460+
taskOpt <- Fox.runOptional(annotation._task)(taskDAO.findOne(_)(GlobalAccessContext)) ?~> "task.notFound"
461461
nmlStream = nmlWriter.toNmlStream(
462462
name,
463463
fetchedSkeletonLayers ::: fetchedVolumeLayers,

app/models/dataset/ThumbnailService.scala

Lines changed: 32 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import models.configuration.DatasetConfigurationService
1414
import net.liftweb.common.Full
1515
import play.api.http.Status.NOT_FOUND
1616
import play.api.i18n.{Messages, MessagesProvider}
17-
import play.api.libs.json.JsArray
17+
import play.api.libs.json.{JsArray, JsObject}
1818
import utils.ObjectId
1919
import utils.sql.{SimpleSQLDAO, SqlClient}
2020

@@ -74,39 +74,41 @@ class ThumbnailService @Inject()(datasetService: DatasetService,
7474
viewConfiguration <- datasetConfigurationService.getDatasetViewConfigurationForDataset(List.empty,
7575
datasetName,
7676
organizationId)(ctx)
77-
(mag1BoundingBox, mag, intensityRangeOpt, colorSettingsOpt) = selectParameters(viewConfiguration,
78-
usableDataSource,
79-
layerName,
80-
layer,
81-
width,
82-
height)
77+
(mag1BoundingBox, mag, intensityRangeOpt, colorSettingsOpt, mapping) = selectParameters(viewConfiguration,
78+
usableDataSource,
79+
layerName,
80+
layer,
81+
width,
82+
height,
83+
mappingName)
8384
client <- datasetService.clientFor(dataset)
8485
image <- client.getDataLayerThumbnail(organizationId,
8586
dataset,
8687
layerName,
8788
mag1BoundingBox,
8889
mag,
89-
mappingName,
90+
mapping,
9091
intensityRangeOpt,
9192
colorSettingsOpt)
9293
_ <- thumbnailDAO.upsertThumbnail(dataset._id,
9394
layerName,
9495
width,
9596
height,
96-
mappingName,
97+
mapping,
9798
image,
9899
jpegMimeType,
99100
mag,
100101
mag1BoundingBox)
101102
} yield image
102103

103-
private def selectParameters(
104-
viewConfiguration: DatasetViewConfiguration,
105-
usableDataSource: GenericDataSource[DataLayerLike],
106-
layerName: String,
107-
layer: DataLayerLike,
108-
targetMagWidth: Int,
109-
targetMagHeigt: Int): (BoundingBox, Vec3Int, Option[(Double, Double)], Option[ThumbnailColorSettings]) = {
104+
private def selectParameters(viewConfiguration: DatasetViewConfiguration,
105+
usableDataSource: GenericDataSource[DataLayerLike],
106+
layerName: String,
107+
layer: DataLayerLike,
108+
targetMagWidth: Int,
109+
targetMagHeigt: Int,
110+
mappingName: Option[String])
111+
: (BoundingBox, Vec3Int, Option[(Double, Double)], Option[ThumbnailColorSettings], Option[String]) = {
110112
val configuredCenterOpt =
111113
viewConfiguration.get("position").flatMap(jsValue => JsonHelper.jsResultToOpt(jsValue.validate[Vec3Int]))
112114
val centerOpt =
@@ -124,7 +126,13 @@ class ThumbnailService @Inject()(datasetService: DatasetService,
124126
val x = center.x - mag1Width / 2
125127
val y = center.y - mag1Height / 2
126128
val z = center.z
127-
(BoundingBox(Vec3Int(x, y, z), mag1Width, mag1Height, 1), mag, intensityRangeOpt, colorSettingsOpt)
129+
130+
val mappingNameResult = mappingName.orElse(readMappingName(viewConfiguration, layerName))
131+
(BoundingBox(Vec3Int(x, y, z), mag1Width, mag1Height, 1),
132+
mag,
133+
intensityRangeOpt,
134+
colorSettingsOpt,
135+
mappingNameResult)
128136
}
129137

130138
private def readIntensityRange(viewConfiguration: DatasetViewConfiguration,
@@ -147,6 +155,13 @@ class ThumbnailService @Inject()(datasetService: DatasetService,
147155
b <- colorArray(2).validate[Int].asOpt
148156
} yield ThumbnailColorSettings(Color(r / 255d, g / 255d, b / 255d, 0), isInverted)
149157

158+
private def readMappingName(viewConfiguration: DatasetViewConfiguration, layerName: String): Option[String] =
159+
for {
160+
layersJsValue <- viewConfiguration.get("layers")
161+
mapping <- (layersJsValue \ layerName \ "mapping").validate[JsObject].asOpt
162+
mappingName <- mapping("name").validate[String].asOpt
163+
} yield mappingName
164+
150165
private def magForZoom(dataLayer: DataLayerLike, zoom: Double): Vec3Int =
151166
dataLayer.resolutions.minBy(r => Math.abs(r.maxDim - zoom))
152167

docs/volume_annotation/import_export.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,11 @@ To import a volume annotation, ensure it is in the correct format (WKW or Zarr)
66
To export (download) an annotation, go to **Menu > Download**. From there, select the data you want to download and choose the desired format (WKW, Zarr). Alternatively, you can open your annotation dashboard and click **Download** next to the annotation.
77

88
![youtube-video](https://www.youtube.com/embed/l8ZacNqvMzI)
9+
10+
## Merging volume annotation with fallback data
11+
12+
After finishing the annotation of a volume layer with a fallback layer, the combined state of these layers can be materialized into a new dataset. For this, go to the layer settings in the left border tab. On the top right of the volume layer is the following button:
13+
14+
![Icon to open the materialize volume annotation modal](../images/materialize_volume_annotation_icon.jpg)
15+
16+
This button opens up a modal that starts a long-running job which will materialize the volume annotation.

docs/volume_annotation/index.md

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,3 @@ WEBKNOSSOS supports volume/segmentation annotations. This annotation type lets y
1010

1111
Watch this tutorial to get started:
1212
![youtube-video](https://www.youtube.com/embed/iw2C7XB6wP4?start=120)
13-
14-
## Merging volume annotation with fallback data
15-
16-
After finishing the annotation of a volume layer with a fallback layer, the combined state of these layers can be materialized into a new dataset. For this, go to the layer settings in the left border tab. On the top right of the volume layer is the following button:
17-
18-
![Icon to open the materialize volume annotation modal](../images/materialize_volume_annotation_icon.jpg)
19-
20-
This button opens up a modal that starts a long-running job which will materialize the volume annotation.

frontend/javascripts/oxalis/view/components/setting_input_views.tsx

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -554,7 +554,6 @@ class UserBoundingBoxInput extends React.PureComponent<UserBoundingBoxInputProps
554554
isLockedByOwner,
555555
isOwner,
556556
);
557-
const isDeleteEnabled = !disabled && this.props.visibleSegmentationLayer != null;
558557

559558
const getContextMenu = () => {
560559
const items: MenuProps["items"] = [
@@ -590,13 +589,13 @@ class UserBoundingBoxInput extends React.PureComponent<UserBoundingBoxInputProps
590589
},
591590
{
592591
key: "delete",
593-
label: isDeleteEnabled ? (
592+
label: !disabled ? (
594593
deleteButton
595594
) : (
596595
<FastTooltip title={editingDisallowedExplanation}>{deleteButton}</FastTooltip>
597596
),
598597
onClick: onDelete,
599-
disabled: !isDeleteEnabled,
598+
disabled,
600599
},
601600
];
602601

0 commit comments

Comments
 (0)