Skip to content

Commit

Permalink
refactor: Replaced DATARANGE_UINT8 with calculated range values
Browse files Browse the repository at this point in the history
  • Loading branch information
ShrimpCryptid committed Dec 13, 2024
1 parent ca984e6 commit 87e1d86
Show file tree
Hide file tree
Showing 8 changed files with 42 additions and 19 deletions.
4 changes: 2 additions & 2 deletions public/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ import {
import { OpenCellLoader } from "../src/loaders/OpenCellLoader";
import { State, TestDataSpec } from "./types";
import VolumeLoaderContext from "../src/workers/VolumeLoaderContext";
import { DATARANGE_UINT8 } from "../src/types";
import { RawArrayLoaderOptions } from "../src/loaders/RawArrayLoader";
import { getDataRange } from "../src/utils/num_utils";

const CACHE_MAX_SIZE = 1_000_000_000;
const CONCURRENCY_LIMIT = 8;
Expand Down Expand Up @@ -877,7 +877,7 @@ function loadImageData(jsonData: ImageInfo, volumeData: Uint8Array[]) {
// according to jsonData.tile_width*jsonData.tile_height*jsonData.tiles
// (first row of first plane is the first data in
// the layout, then second row of first plane, etc)
vol.setChannelDataFromVolume(i, volumeData[i], DATARANGE_UINT8);
vol.setChannelDataFromVolume(i, volumeData[i], getDataRange(volumeData[i]));

setInitialRenderMode();

Expand Down
4 changes: 2 additions & 2 deletions src/PathTracedVolume.ts
Original file line number Diff line number Diff line change
Expand Up @@ -492,11 +492,11 @@ export default class PathTracedVolume implements VolumeRenderImpl {
// TODO expand to 16-bpp raw intensities?
this.pathTracingUniforms.gIntensityMax.value.setComponent(
i,
this.volume.channels[channel].histogram.getMax() / 255.0
this.volume.channels[channel].histogram.getDataMax() / 255.0
);
this.pathTracingUniforms.gIntensityMin.value.setComponent(
i,
this.volume.channels[channel].histogram.getMin() / 255.0
this.volume.channels[channel].histogram.getDataMin() / 255.0
);
}
this.pathTracingUniforms.gLutTexture.value.needsUpdate = true;
Expand Down
19 changes: 13 additions & 6 deletions src/loaders/JsonImageInfoLoader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { computeAtlasSize, type ImageInfo } from "../ImageInfo.js";
import type { VolumeDims } from "../VolumeDims.js";
import VolumeCache from "../VolumeCache.js";
import type { TypedArray, NumberType } from "../types.js";
import { DATARANGE_UINT8 } from "../types.js";
import { getDataRange } from "../utils/num_utils.js";

interface PackedChannelsImage {
name: string;
Expand Down Expand Up @@ -262,14 +262,15 @@ class JsonImageInfoLoader extends ThreadableVolumeLoader {
const cacheResult = cache?.get(`${image.name}/${chindex}`);
if (cacheResult) {
// all data coming from this loader is natively 8-bit
const channelData = new Uint8Array(cacheResult);
if (syncChannels) {
// if we are synchronizing channels, we need to keep track of the data
resultChannelIndices.push(chindex);
resultChannelDtype.push("uint8");
resultChannelData.push(new Uint8Array(cacheResult));
resultChannelRanges.push(DATARANGE_UINT8);
resultChannelData.push(channelData);
resultChannelRanges.push(getDataRange(channelData));
} else {
onData([chindex], ["uint8"], [new Uint8Array(cacheResult)], [DATARANGE_UINT8]);
onData([chindex], ["uint8"], [new Uint8Array(cacheResult)], [getDataRange(channelData)]);
}
} else {
cacheHit = false;
Expand Down Expand Up @@ -308,10 +309,16 @@ class JsonImageInfoLoader extends ThreadableVolumeLoader {
}

// extract the data
let rawRange: [number, number][] = [];

Check warning on line 312 in src/loaders/JsonImageInfoLoader.ts

View workflow job for this annotation

GitHub Actions / ✅ Lint

'rawRange' is never reassigned. Use 'const' instead
for (let j = 0; j < Math.min(image.channels.length, 4); ++j) {
let rawMin = Infinity;
let rawMax = -Infinity;
for (let px = 0; px < length; px++) {
channelsBits[j][px] = iData.data[px * 4 + j];
rawMin = Math.min(rawMin, channelsBits[j][px]);
rawMax = Math.max(rawMax, channelsBits[j][px]);
}
rawRange[j] = [rawMin, rawMax];
}

// done with `iData` and `canvas` now.
Expand All @@ -325,9 +332,9 @@ class JsonImageInfoLoader extends ThreadableVolumeLoader {
resultChannelIndices.push(chindex);
resultChannelDtype.push("uint8");
resultChannelData.push(channelsBits[ch]);
resultChannelRanges.push(DATARANGE_UINT8);
resultChannelRanges.push(rawRange[ch]);
} else {
onData([chindex], ["uint8"], [channelsBits[ch]], [DATARANGE_UINT8], [bitmap.width, bitmap.height]);
onData([chindex], ["uint8"], [channelsBits[ch]], [rawRange[ch]], [bitmap.width, bitmap.height]);
}
}
});
Expand Down
10 changes: 8 additions & 2 deletions src/loaders/OpenCellLoader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { ThreadableVolumeLoader, LoadSpec, RawChannelDataCallback, LoadedVolumeI
import { computeAtlasSize, type ImageInfo } from "../ImageInfo.js";
import type { VolumeDims } from "../VolumeDims.js";
import { JsonImageInfoLoader } from "./JsonImageInfoLoader.js";
import { DATARANGE_UINT8 } from "../types.js";
import { getDataRange } from "../utils/num_utils.js";

class OpenCellLoader extends ThreadableVolumeLoader {
async loadDims(_: LoadSpec): Promise<VolumeDims[]> {
Expand Down Expand Up @@ -74,7 +74,13 @@ class OpenCellLoader extends ThreadableVolumeLoader {
const [w, h] = computeAtlasSize(imageInfo);
// all data coming from this loader is natively 8-bit
return JsonImageInfoLoader.loadVolumeAtlasData(urls, (ch, dtype, data) =>
onData(ch, dtype, data, [DATARANGE_UINT8], [w, h])
onData(
ch,
dtype,
data,
data.map((arr) => getDataRange(arr)),
[w, h]
)
);
}
}
Expand Down
6 changes: 4 additions & 2 deletions src/loaders/RawArrayLoader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ import {
import { computePackedAtlasDims } from "./VolumeLoaderUtils.js";
import type { ImageInfo } from "../ImageInfo.js";
import type { VolumeDims } from "../VolumeDims.js";
import { DATARANGE_UINT8, Uint8 } from "../types.js";
import { Uint8 } from "../types.js";
import { getDataRange } from "../utils/num_utils.js";

// this is the form in which a 4D numpy array arrives as converted
// by jupyterlab into a js object.
Expand Down Expand Up @@ -135,8 +136,9 @@ class RawArrayLoader extends ThreadableVolumeLoader {
}
const volSizeBytes = this.data.shape[3] * this.data.shape[2] * this.data.shape[1]; // x*y*z pixels * 1 byte/pixel
const channelData = new Uint8Array(this.data.buffer.buffer, chindex * volSizeBytes, volSizeBytes);
const range = getDataRange(channelData);
// all data coming from this loader is natively 8-bit
onData([chindex], ["uint8"], [channelData], [DATARANGE_UINT8]);
onData([chindex], ["uint8"], [channelData], [range]);
}

return Promise.resolve();
Expand Down
6 changes: 3 additions & 3 deletions src/test/volume.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import Volume from "../Volume";
import VolumeMaker from "../VolumeMaker";
import { LUT_ARRAY_LENGTH } from "../Lut";
import Channel from "../Channel";
import { DATARANGE_UINT8 } from "../types";
import { CImageInfo, ImageInfo } from "../ImageInfo";
import { getDataRange } from "../utils/num_utils";

// PREPARE SOME TEST DATA TO TRY TO DISPLAY A VOLUME.
const testimgdata: ImageInfo = {
Expand Down Expand Up @@ -87,14 +87,14 @@ describe("test volume", () => {

const conedata = VolumeMaker.createCone(size.x, size.y, size.z, size.x / 8, size.z);

v.setChannelDataFromVolume(0, conedata, DATARANGE_UINT8);
v.setChannelDataFromVolume(0, conedata, getDataRange(conedata));

const c0 = v.getChannel(0);
checkChannelDataConstruction(c0, 0, testimgdata);

const spheredata = VolumeMaker.createSphere(size.x, size.y, size.z, size.z / 4);

v.setChannelDataFromVolume(1, spheredata, DATARANGE_UINT8);
v.setChannelDataFromVolume(1, spheredata, getDataRange(spheredata));

const c1 = v.getChannel(1);
checkChannelDataConstruction(c1, 1, testimgdata);
Expand Down
2 changes: 0 additions & 2 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -150,5 +150,3 @@ export const isTop = (corner: ViewportCorner): boolean =>
corner === ViewportCorner.TOP_LEFT || corner === ViewportCorner.TOP_RIGHT;
export const isRight = (corner: ViewportCorner): boolean =>
corner === ViewportCorner.TOP_RIGHT || corner === ViewportCorner.BOTTOM_RIGHT;

export const DATARANGE_UINT8: [number, number] = [0, 255];
10 changes: 10 additions & 0 deletions src/utils/num_utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -230,3 +230,13 @@ export function constrainToAxis(
return [...src];
}
}

export function getDataRange(data: ArrayLike<number>): [number, number] {
let min = Infinity;
let max = -Infinity;
for (let i = 0; i < data.length; i++) {
min = Math.min(min, data[i]);
max = Math.max(max, data[i]);
}
return [min, max];
}

0 comments on commit 87e1d86

Please sign in to comment.