Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
39 changes: 36 additions & 3 deletions src/components/ui/MainPanel/MetaDataInfo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,37 @@ const MetaDataInfo = ({ meta, metadata, setShowMeta, setOpenVariables, popoverSi
const zLength = useMemo(() => meta.shape ? meta.shape[shapeLength-3] : 0, [meta])
const yLength = useMemo(() => meta.shape ? meta.shape[shapeLength-2] : 0, [meta])
const xLength = useMemo(() => meta.shape ? meta.shape[shapeLength-1] : 0, [meta])
const dataShape = coarsen ? meta.shape.map((val: number, idx: number) => Math.floor(idx === 0 ? val/kernelDepth : val/kernelSize)): meta.shape
const chunkShape = coarsen ? meta.chunks.map((val: number, idx: number) => Math.floor(idx === 0 ? val/kernelDepth : val/kernelSize)): meta.chunks
const { dataShape, chunkShape } = useMemo(() => {
if (coarsen) {
const n = meta.shape.length;
const Coarsen = (val: number, idx:number ) =>{
if (n <= 2) {
return Math.floor(val / kernelSize);
}
const thirdLast = n - 3;
const secondLast = n - 2;
const last = n - 1;
if (idx === thirdLast) {
return Math.floor(val / kernelDepth);
}
if (idx === secondLast || idx === last) {
return Math.floor(val / kernelSize);
}
return val;
}
const dataShape = meta.shape.map((val: number, idx: number) => {
return Coarsen(val, idx)
});
const chunkShape = meta.chunks.map((val: number, idx: number) => {
return Coarsen(val, idx)
});
return { dataShape, chunkShape };
}
return {
dataShape: meta.shape,
chunkShape: meta.chunks
};
}, [meta, coarsen, kernelDepth, kernelSize]);

// ---- Booleans ---- //
const is3D = useMemo(() => meta.shape ? meta.shape.length == 3 : false, [meta])
Expand Down Expand Up @@ -235,7 +264,11 @@ const MetaDataInfo = ({ meta, metadata, setShowMeta, setOpenVariables, popoverSi
</div>
<Hider show={coarsen} className="mt-2">
<div className="grid grid-cols-2 gap-x-1">
<div className="grid grid-cols-[auto_50px]">
<div className="grid grid-cols-[auto_50px]"
style={{
visibility: dataShape.length >= 3 ? 'visible' : 'hidden'
}}
>
<b>Temporal Coarsening</b>
<Input type='number' min='0' step={1} value={displayDepth}
onChange={e=>{
Expand Down
3 changes: 2 additions & 1 deletion src/components/ui/MainPanel/PlayButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,8 @@ const PlayInterFace = ({visible, setKeepOpen}:{visible : boolean, setKeepOpen: R
let timeSlice = timeArray?.slice(zSlice[0], zSlice[1] ?? undefined)
const timeLength = timeArray?.length || 1
let sliceDist = zSlice[1] ? zSlice[1] - zSlice[0] : timeLength - zSlice[0]
if (coarsen) {

if (coarsen && timeSlice) {
timeSlice = coarsenFlatArray(timeSlice, kernel.kernelDepth)
sliceDist = Math.floor(sliceDist/kernel.kernelDepth)
}
Expand Down
83 changes: 38 additions & 45 deletions src/components/zarr/ZarrGetters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { useZarrStore, useCacheStore, useGlobalStore, useErrorStore } from "@/Gl
import * as zarr from 'zarrita';
import { CompressArray, DecompressArray, ZarrError, RescaleArray, ToFloat16, copyChunkToArray } from "./ZarrLoaderLRU";
import { GetSize } from "./GetMetadata";
import { Convolve } from "../computation/webGPU";
import { Convolve, Convolve2D } from "../computation/webGPU";
import { coarsen3DArray, calculateStrides } from "@/utils/HelperFuncs";

export async function GetZarrDims(variable: string){
Expand Down Expand Up @@ -149,52 +149,45 @@ export async function GetZarrArray(){
if (is4D){
chunkShape = chunkShape.slice(1);
}
const is2D = outVar.shape.length === 2;

const notChunked = fullShape.every((dim, idx) => dim > chunkShape[idx]);

// ---- I THINK THIS CODE IS REDUNDANT. BUT NEED TO TEST ON AN UNCHUNCKED ZARR DATASET TO BE SURE ---- //

// //---- Strategy 1. Download whole array (No time chunks) ----//
// if (notChunked){
// setStatus("Downloading...")
// const chunk = await fetchWithRetry(
// () => is4D ? zarr.get(outVar, [idx4D, null, null, null]) : zarr.get(outVar),
// `variable ${variable}`,
// setStatus
// );
// if (!chunk) throw new Error('Unexpected: chunk was not assigned'); // This is redundant but satisfies TypeScript
// if (chunk.data instanceof BigInt64Array || chunk.data instanceof BigUint64Array) {
// throw new Error("BigInt arrays not supported.");
// }
// const shape = is4D ? outVar.shape.slice(1) : outVar.shape;
// const strides = chunk.stride;
// setStrides(strides) // Need strides for the point cloud

// let [typedArray, scalingFactor] = ToFloat16(chunk.data.map((v: number) => v === fillValue ? NaN : v) as Float32Array, null)
// if (coarsen){
// typedArray = await Convolve(typedArray, {shape, strides}, "Mean", {kernelSize, kernelDepth}) as Float16Array
// const newShape = shape.map((dim, idx) => Math.ceil(dim / (idx === 0 ? kernelDepth : kernelSize)))
// let newStrides = newShape.slice()
// newStrides = newStrides.map((val, idx) => {
// return newStrides.reduce((a, b, i) => a * (i < idx ? b : 1), 1)
// })
// console.log(newStrides)
// }
// const cacheChunk = {
// data: compress ? CompressArray(typedArray, 7) : typedArray,
// shape: chunk.shape,
// stride: chunk.stride,
// scaling: scalingFactor,
// compressed: compress
// }
// cache.set(is4D ? `${initStore}_${idx4D}_${variable}` : `${initStore}_${variable}`, cacheChunk)
// setStatus(null)
// return { data: typedArray, shape, dtype: outVar.dtype, scalingFactor };
// }
// //---- Strategy 1. Download whole array (Chunking Logic doesn't work on 2D atm) ----//
if (is2D){
setStatus("Downloading...")
const chunk = await fetchWithRetry(
() => zarr.get(outVar),
`variable ${variable}`,
setStatus
);
if (!chunk) throw new Error('Unexpected: chunk was not assigned'); // This is redundant but satisfies TypeScript
if (chunk.data instanceof BigInt64Array || chunk.data instanceof BigUint64Array) {
throw new Error("BigInt arrays not supported.");
}
const shape = outVar.shape;
const strides = chunk.stride;
setStrides(strides) // Need strides for the point cloud

//---- Strategy 2. Download Chunks ----//
const is2D = outVar.shape.length === 2;

let [typedArray, scalingFactor] = ToFloat16(chunk.data.map((v: number) => v === fillValue ? NaN : v) as Float32Array, null)
if (coarsen){
typedArray = await Convolve2D(typedArray, {shape, strides}, "Mean2D", kernelSize) as Float16Array
const newShape = shape.map((dim) => Math.ceil(dim / kernelSize))
let newStrides = newShape.slice()
newStrides = newStrides.map((_val, idx) => {
return newStrides.reduce((a, b, i) => a * (i < idx ? b : 1), 1)
})
}
const cacheChunk = {
data: compress ? CompressArray(typedArray, 7) : typedArray,
shape: chunk.shape,
stride: chunk.stride,
scaling: scalingFactor,
compressed: compress
}
cache.set(`${initStore}_${variable}`, cacheChunk)
setStatus(null)
return { data: typedArray, shape, dtype: outVar.dtype, scalingFactor };
}

// Calculate Indices
const zIndexOffset = is4D ? 1 : 0;

Expand Down
Loading