Skip to content

Commit

Permalink
Merge pull request #266 from allen-cell-animated/fix/remove-volume
Browse files Browse the repository at this point in the history
Bug fix for Json images, and remove image
  • Loading branch information
toloudis authored Dec 4, 2024
2 parents d3bbd38 + 225e8e2 commit b141f39
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 9 deletions.
1 change: 0 additions & 1 deletion src/Atlas2DSlice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,6 @@ export default class Atlas2DSlice implements VolumeRenderImpl {
public updateVolumeDimensions(): void {
const volumeScale = this.volume.normPhysicalSize.clone().multiply(this.settings.scale);
const regionScale = volumeScale.clone().multiply(this.volume.normRegionSize);
console.log(regionScale);
const volumeOffset = this.volume.getContentCenter().clone().multiply(this.settings.scale);
this.geometryMesh.position.copy(volumeOffset);
// set scale
Expand Down
1 change: 1 addition & 0 deletions src/View3d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,7 @@ export class View3d {
if (this.image) {
this.removeVolume(this.image.volume);
}
this.image = undefined;
}

/**
Expand Down
7 changes: 4 additions & 3 deletions src/VolumeDrawable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,8 @@ export default class VolumeDrawable {
}

/**
* Updates whether a channel's data must be loaded for rendering, based on if its volume or isosurface is enabled.
* Updates whether a channel's data must be loaded for rendering,
* based on if its volume or isosurface is enabled, or whether it is needed for masking.
* Calls `Volume.updateRequiredData` to update the list of required channels if necessary.
*/
private updateChannelDataRequired(channelIndex: number): void {
Expand All @@ -128,12 +129,12 @@ export default class VolumeDrawable {

if (requiredChannels.includes(channelIndex)) {
if (!channelIsRequired) {
// This channel is currently marked required, but both its volume and isosurface are off. Remove it!
// This channel is currently marked required, but both its volume and isosurface are off, and it's not a mask. Remove it!
this.volume.updateRequiredData({ channels: requiredChannels.filter((i) => i !== channelIndex) });
}
} else {
if (channelIsRequired) {
// This channel is not marked required, but either its volume or isosurface is on. Add it!
// This channel is not marked required, but either its volume or isosurface is on, or it is a mask. Add it!
this.volume.updateRequiredData({ channels: [...requiredChannels, channelIndex] });
}
}
Expand Down
39 changes: 34 additions & 5 deletions src/loaders/JsonImageInfoLoader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ const convertImageInfo = (json: JsonImageInfo): ImageInfo => {
class JsonImageInfoLoader extends ThreadableVolumeLoader {
urls: string[];
jsonInfo: (JsonImageInfo | undefined)[];
syncChannels = false;

cache?: VolumeCache;

Expand Down Expand Up @@ -152,6 +153,10 @@ class JsonImageInfoLoader extends ThreadableVolumeLoader {
return imageInfo;
}

syncMultichannelLoading(sync: boolean): void {
this.syncChannels = sync;
}

async loadDims(loadSpec: LoadSpec): Promise<VolumeDims[]> {
const jsonInfo = await this.getJsonImageInfo(loadSpec.time);

Expand Down Expand Up @@ -192,7 +197,7 @@ class JsonImageInfoLoader extends ThreadableVolumeLoader {
const requestedChannels = loadSpec.channels;
if (requestedChannels) {
// If only some channels are requested, load only images which contain at least one requested channel
images = images.filter(({ channels }) => channels.some((ch) => ch in requestedChannels));
images = images.filter(({ channels }) => channels.some((ch) => requestedChannels.includes(ch)));
}

// This regex removes everything after the last slash, so the url had better be simple.
Expand All @@ -217,7 +222,7 @@ class JsonImageInfoLoader extends ThreadableVolumeLoader {
data: TypedArray<NumberType>[],
ranges: [number, number][]
) => onData(ch, dtype, data, ranges, [w, h]);
await JsonImageInfoLoader.loadVolumeAtlasData(images, wrappedOnData, this.cache);
await JsonImageInfoLoader.loadVolumeAtlasData(images, wrappedOnData, this.cache, this.syncChannels);
}

/**
Expand All @@ -239,8 +244,14 @@ class JsonImageInfoLoader extends ThreadableVolumeLoader {
static async loadVolumeAtlasData(
imageArray: PackedChannelsImage[],
onData: RawChannelDataCallback,
cache?: VolumeCache
cache?: VolumeCache,
syncChannels = false
): Promise<void> {
const resultChannelIndices: number[] = [];
const resultChannelDtype: NumberType[] = [];
const resultChannelData: TypedArray<NumberType>[] = [];
const resultChannelRanges: [number, number][] = [];

const imagePromises = imageArray.map(async (image) => {
// Because the data is fetched such that one fetch returns a whole batch,
// if any in batch is cached then they all should be. So if any in batch is NOT cached,
Expand All @@ -251,7 +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
onData([chindex], ["uint8"], [new Uint8Array(cacheResult)], [DATARANGE_UINT8]);
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);
} else {
onData([chindex], ["uint8"], [new Uint8Array(cacheResult)], [DATARANGE_UINT8]);
}
} else {
cacheHit = false;
// we can stop checking because we know we are going to have to fetch the whole batch
Expand Down Expand Up @@ -302,11 +321,21 @@ class JsonImageInfoLoader extends ThreadableVolumeLoader {
cache?.insert(`${image.name}/${chindex}`, channelsBits[ch]);
// NOTE: the atlas dimensions passed in here are currently unused by `JSONImageInfoLoader`
// all data coming from this loader is natively 8-bit
onData([chindex], ["uint8"], [channelsBits[ch]], [DATARANGE_UINT8], [bitmap.width, bitmap.height]);
if (syncChannels) {
resultChannelIndices.push(chindex);
resultChannelDtype.push("uint8");
resultChannelData.push(channelsBits[ch]);
resultChannelRanges.push(DATARANGE_UINT8);
} else {
onData([chindex], ["uint8"], [channelsBits[ch]], [DATARANGE_UINT8], [bitmap.width, bitmap.height]);
}
}
});

await Promise.all(imagePromises);
if (syncChannels) {
onData(resultChannelIndices, resultChannelDtype, resultChannelData, resultChannelRanges);
}
}
}

Expand Down

0 comments on commit b141f39

Please sign in to comment.