Skip to content

Commit

Permalink
Merge pull request #108 from RationAI/development
Browse files Browse the repository at this point in the history
Improve module for wsi-service communication.
  • Loading branch information
Aiosa authored Nov 27, 2024
2 parents f6f5d6a + 995d0f7 commit 5eaf40f
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 38 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
The changelog file describes changes made since v2.0.0, which made significant changes
to the versions 1.x.x.

### Unreleased 2.1.1
**Features:** standalone wsi tile source module.

### 2.1.0
**Features:** new system for module/plugin building, improvements of annotation listing features,
support for generic annotation visual style changes.
Expand Down
23 changes: 1 addition & 22 deletions modules/empaia-wsi-tile-source/README.md
Original file line number Diff line number Diff line change
@@ -1,24 +1,3 @@
# Standalone WSI Service

Implementation of OpenSeadragon Tile Source access to the standalone WSI service.

> [!CAUTION]
> This module collides with different empaia slide service access (e.g. `EmpationAPI`) - the protocols used
> are the same and only one will be used (without user control over which one).
Modified by RationAI, the WSI service can read proprietary WSI file formats
in the standalone mode, accessing WSIs by their standalone IDs (generated via the service local path mapper),
or accessing the files directly by a file path (must replace `/` chars with `>` for `/slides` endpoint).

Also supports multifile access on the API extension `/files`.

### Usage

You need to provide an URL to the WSI server that uses empaia API, for example:
````json
"image_group_server": "http://localhost:8080",
"image_group_protocol": "`${path}/v3/batch/info?slides=${data}`",
"image_group_preview": "`${path}/v3/batch/thumbnail/max_size/250/250?slides=${data}`",
"data_group_server": "http://localhost:8080",
"data_group_protocol": "`${path}/v3/batch/info?slides=${data.join(\",\")}`",
````
Deprecated. Use rationai-wsi-tile-source instead.
12 changes: 7 additions & 5 deletions modules/empaia-wsi-tile-source/tile-source.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ OpenSeadragon.EmpaiaStandaloneV3TileSource = class extends OpenSeadragon.TileSou
supports( data, url ) {
if (url && Array.isArray(data)) {
//multi-tile or single tile access
let match = url.match(/^(\/?[^\/].*\/v3\/batch)\/info/i);
let match = url.match(/^(\/?[^\/].*\/v3\/files)\/info/i);
if (match) {
data = data || [{}];
data[0].tilesUrl = match[1];
Expand Down Expand Up @@ -159,11 +159,13 @@ OpenSeadragon.EmpaiaStandaloneV3TileSource = class extends OpenSeadragon.TileSou
}

_getInfo(url, tilesUrl) {
fetch(url).then(res => {
fetch(url).then(async res => {
const text = await res.text();
const json = JSON.parse(text);
if (res.status !== 200) {
throw new HTTPError("Empaia standalone failed to fetch image info!", res, res.error);
throw new HTTPError("Empaia standalone failed to fetch image info!", json, res.error);
}
return res.json();
return json;
}).then(imageInfo => {
const data = this.configure(imageInfo, url, null);
// necessary TileSource props that wont get set manually
Expand Down Expand Up @@ -208,7 +210,7 @@ OpenSeadragon.EmpaiaStandaloneV3TileSource = class extends OpenSeadragon.TileSou
level = this.maxLevel-level; //OSD assumes max level is biggest number, query vice versa,

if (this.multifetch) {
//endpoint batch/tile/level/[L]/tile/[X]/[Y]/?paths=path,list,separated,by,commas
//endpoint files/tile/level/[L]/tile/[X]/[Y]/?paths=path,list,separated,by,commas
return `${tiles}/tile/level/${level}/tile/${x}/${y}?slides=${this.fileId}`
}
//endpoint slides/[SLIDE]/tile/level/[L]/tile/[X]/[Y]/
Expand Down
29 changes: 29 additions & 0 deletions modules/rationai-wsi-tile-source/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Standalone WSI Service

Implementation of OpenSeadragon Tile Source access to the standalone WSI service.

Modified by RationAI, the WSI service can read proprietary WSI file formats
in the standalone mode, accessing WSIs by their IDs (dependent on the mapper usage).

Also supports multifile access on the API extension `/files`.

### Usage
Configure the default viewer ENV
````json
"image_group_server": "http://localhost:8080",
"image_group_protocol": "{url: `$${path}/v3/files/info?paths=$${data}`, type: 'empaia-standalone'}",
"image_group_preview": "`${path}/v3/batch/thumbnail/max_size/250/250?slides=${data}`",
"data_group_server": "http://localhost:8080",
"data_group_protocol": "{url:`$${path}/v3/files/info?paths=$${data.join(\",\")}`, type: 'empaia-standalone'}",
````
or provide particular strings in the ``protocol`` for sessions.

You can also just set an URL to the WSI server, for example:
````json
"image_group_server": "http://localhost:8080",
"image_group_protocol": "`${path}/v3/batch/info?slides=${data}`",
"image_group_preview": "`${path}/v3/batch/thumbnail/max_size/250/250?slides=${data}`",
"data_group_server": "http://localhost:8080",
"data_group_protocol": "`${path}/v3/batch/info?slides=${data.join(\",\")}`",
````
But this approach has its limitations.
24 changes: 13 additions & 11 deletions modules/rationai-wsi-tile-source/tile-source.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
// noinspection JSUnresolvedVariable

/**
* @class EmpaiaStandaloneV3TileSource
* @class RationaiStandaloneV3TileSource
* @memberof OpenSeadragon
* @extends OpenSeadragon.TileSource
* @param {object} options configuration either empaia info response or list of these objects
*/
OpenSeadragon.EmpaiaStandaloneV3TileSource = class extends OpenSeadragon.TileSource {
OpenSeadragon.RationaiStandaloneV3TileSource = class extends OpenSeadragon.TileSource {

constructor(options) {
super(options);
Expand Down Expand Up @@ -52,7 +52,7 @@ OpenSeadragon.EmpaiaStandaloneV3TileSource = class extends OpenSeadragon.TileSou

if (!url || !Array.isArray(data) || typeof data !== "object") return false;
//multi-tile or single tile access
let match = url.match(/^(\/?[^\/].*\/v3\/batch)\/info/i);
let match = url.match(/^(\/?[^\/].*\/v3\/files)\/info/i);
if (match) {
data = data || [{}];
data[0].tilesUrl = match[1];
Expand Down Expand Up @@ -199,7 +199,7 @@ OpenSeadragon.EmpaiaStandaloneV3TileSource = class extends OpenSeadragon.TileSou
getImageInfo(url) {
if (!this._handlesOwnImageLoadLogics) return super.getImageInfo(url);

let match = url.match(/^(\/?[^\/].*\/v3\/batch)\/info/i);
let match = url.match(/^(\/?[^\/].*\/v3\/files)\/info/i);
if (match) {
this._setDownloadHandler(true);
return this._getInfo(url, match[1]);
Expand All @@ -215,11 +215,13 @@ OpenSeadragon.EmpaiaStandaloneV3TileSource = class extends OpenSeadragon.TileSou
_getInfo(url, tilesUrl) {
fetch(url, {
headers: this.ajaxHeaders || {}
}).then(res => {
}).then(async res => {
const text = await res.text();
const json = JSON.parse(text);
if (res.status !== 200) {
throw new HTTPError("Empaia standalone failed to fetch image info!", res, res.error);
throw new HTTPError("Empaia standalone failed to fetch image info!", json, res.error);
}
return res.json();
return json;
}).then(imageInfo => {
const data = this.configure(imageInfo, url, null);
// necessary TileSource props that wont get set manually
Expand Down Expand Up @@ -264,11 +266,11 @@ OpenSeadragon.EmpaiaStandaloneV3TileSource = class extends OpenSeadragon.TileSou
level = this.maxLevel-level; //OSD assumes max level is biggest number, query vice versa,

if (this.multifetch) {
//endpoint batch/tile/level/[L]/tile/[X]/[Y]/?paths=path,list,separated,by,commas
return `${tiles}/tile/level/${level}/tile/${x}/${y}?slides=${this.fileId}`
//endpoint files/tile/level/[L]/tile/[X]/[Y]/?paths=id,list,separated,by,commas
return `${tiles}/tile/level/${level}/tile/${x}/${y}?paths=${this.fileId}`
}
//endpoint slides/[SLIDE]/tile/level/[L]/tile/[X]/[Y]/
return `${tiles}/tile/level/${level}/tile/${x}/${y}?slide=${this.fileId}`
//endpoint slides/tile/level/[L]/tile/[X]/[Y]/?slide_id=id
return `${tiles}/tile/level/${level}/tile/${x}/${y}?slide_id=${this.fileId}`
}

_setDownloadHandler(isMultiplex) {
Expand Down

0 comments on commit 5eaf40f

Please sign in to comment.