diff --git a/src/components/plots/AnalysisWG.tsx b/src/components/plots/AnalysisWG.tsx index d7bccbbf..48aa6278 100644 --- a/src/components/plots/AnalysisWG.tsx +++ b/src/components/plots/AnalysisWG.tsx @@ -45,10 +45,10 @@ type Operation = keyof typeof ShaderMap; const AnalysisWG = ({ setTexture, }: { setTexture: React.Dispatch> }) => { // Global state hooks remain the same - const { strides, dataShape, valueScales, isFlat, plotOn, setIsFlat, setStatus, setValueScales } = useGlobalStore(useShallow(state => ({ + const { strides, dataShape, valueScales, isFlat, plotOn, setIsFlat, setStatus, setValueScales, variable } = useGlobalStore(useShallow(state => ({ strides: state.strides, dataShape: state.dataShape, valueScales: state.valueScales, isFlat: state.isFlat, plotOn:state.plotOn, setIsFlat: state.setIsFlat, setStatus: state.setStatus, - setValueScales: state.setValueScales, + setValueScales: state.setValueScales, variable: state.variable }))); const setPlotType = usePlotStore(state => state.setPlotType); @@ -98,7 +98,7 @@ const AnalysisWG = ({ setTexture, }: { setTexture: React.DispatchplotType == 'point-cloud',[plotType]) const globalScale = isPC ? dataShape[2]/AXIS_CONSTANTS.PC_GLOBAL_SCALE_DIVISOR : 1 - const depthRatio = useMemo(()=>shape.z/shape.x*timeScale,[shape, timeScale]); + const depthRatio = useMemo(() => { + if (isPC && dataShape && dataShape[2]) { + return (dataShape[0] / dataShape[2]) * timeScale; + } + return (shape.z / shape.x) * timeScale; + }, [isPC, dataShape, shape, timeScale]); const shapeRatio = useMemo(()=>shape.y/shape.x, [shape]) const timeRatio = useMemo(()=>Math.max(shape.z/shape.x * 2, 2),[shape]); diff --git a/src/components/plots/FlatMap.tsx b/src/components/plots/FlatMap.tsx index 16b549d2..f164748a 100644 --- a/src/components/plots/FlatMap.tsx +++ b/src/components/plots/FlatMap.tsx @@ -28,7 +28,7 @@ const FlatMap = ({textures: propTextures, infoSetters} : {textures : THREE.DataT const {setLoc, setShowInfo, val, coords} = infoSetters; const {flipY, colormap, dimArrays, dimNames, dimUnits, isFlat, dataShape, textureArrayDepths, strides, remapTexture, shape, - setPlotDim,updateDimCoords, updateTimeSeries} = useGlobalStore(useShallow(state => ({ + setPlotDim,updateDimCoords, updateTimeSeries, variable} = useGlobalStore(useShallow(state => ({ flipY: state.flipY, colormap: state.colormap, dimArrays: state.dimArrays, strides: state.strides, dimNames:state.dimNames, dimUnits: state.dimUnits, @@ -37,7 +37,8 @@ const FlatMap = ({textures: propTextures, infoSetters} : {textures : THREE.DataT remapTexture:state.remapTexture, shape: state.shape, setPlotDim:state.setPlotDim, updateDimCoords:state.updateDimCoords, - updateTimeSeries: state.updateTimeSeries + updateTimeSeries: state.updateTimeSeries, + variable: state.variable }))) const {cScale, cOffset, animProg, nanTransparency, nanColor, @@ -94,7 +95,7 @@ const FlatMap = ({textures: propTextures, infoSetters} : {textures : THREE.DataT const infoRef = useRef(false) const lastUV = useRef(new THREE.Vector2(0,0)) const rotateMap = analysisMode && axis == 2; - const sampleArray = useMemo(()=> analysisMode ? analysisArray : GetCurrentArray(),[analysisMode, analysisArray, textures]) + const sampleArray = useMemo(()=> (analysisMode && analysisArray) ? analysisArray : GetCurrentArray(undefined, variable, dataShape, strides),[analysisMode, analysisArray, textures, variable, dataShape, strides]) const analysisDims = useMemo(() => { if (!analysisMode) return dimSlices; const fullSlices = [ @@ -143,7 +144,7 @@ const FlatMap = ({textures: propTextures, infoSetters} : {textures : THREE.DataT const normal = new THREE.Vector3(0,0,1) if(uv){ const tsUV = flipY ? new THREE.Vector2(uv.x, 1-uv.y) : uv - const tempTS = GetTimeSeries({data:analysisMode ? analysisArray : GetCurrentArray(), shape:dataShape, stride:strides},{uv:tsUV,normal}) + const tempTS = GetTimeSeries({data: ((analysisMode && analysisArray)) ? analysisArray : GetCurrentArray(undefined, variable, dataShape, strides), shape:dataShape, stride:strides},{uv:tsUV,normal}) setPlotDim(0) //I think this 2 is only if there are 3-dims. Need to rework the logic const coordUV = parseUVCoords({normal:normal,uv:uv}) diff --git a/src/components/plots/Sphere.tsx b/src/components/plots/Sphere.tsx index 26a7ae06..e53e8de6 100644 --- a/src/components/plots/Sphere.tsx +++ b/src/components/plots/Sphere.tsx @@ -31,7 +31,7 @@ export const Sphere = ({textures: propTextures} : {textures: THREE.Data3DTexture analysisArray: state.analysisArray }))) const {colormap, isFlat, dimArrays, dimNames, dimUnits, valueScales, - dataShape, strides, flipY, textureArrayDepths} = useGlobalStore(useShallow(state=>({ + dataShape, strides, flipY, textureArrayDepths, variable} = useGlobalStore(useShallow(state=>({ colormap: state.colormap, isFlat: state.isFlat, dimArrays:state.dimArrays, @@ -41,7 +41,8 @@ export const Sphere = ({textures: propTextures} : {textures: THREE.Data3DTexture dataShape: state.dataShape, strides: state.strides, flipY: state.flipY, - textureArrayDepths: state.textureArrayDepths + textureArrayDepths: state.textureArrayDepths, + variable: state.variable }))) const {animate, animProg, cOffset, cScale, valueRange, selectTS, nanColor, nanTransparency, sphereDisplacement, sphereResolution, @@ -154,7 +155,7 @@ export const Sphere = ({textures: propTextures} : {textures: THREE.Data3DTexture const uv = XYZtoRemap(point, latBounds, lonBounds); const normal = new THREE.Vector3(0,0,1) const tsUV = flipY ? new THREE.Vector2(uv.x, 1-uv.y) : uv - const tempTS = GetTimeSeries({data:analysisMode ? analysisArray : GetCurrentArray(), shape:dataShape, stride:strides},{uv:tsUV,normal}) + const tempTS = GetTimeSeries({data: (analysisMode && analysisArray) ? analysisArray : GetCurrentArray(undefined, variable, dataShape, strides), shape:dataShape, stride:strides},{uv:tsUV,normal}) setPlotDim(0) //I think this 2 is only if there are 3-dims. Need to rework the logic const coordUV = parseUVCoords({normal:normal,uv:uv}) diff --git a/src/components/plots/UVCube.tsx b/src/components/plots/UVCube.tsx index 301caa68..19e22bdf 100644 --- a/src/components/plots/UVCube.tsx +++ b/src/components/plots/UVCube.tsx @@ -78,14 +78,15 @@ export const UVCube = ( {scale} : {scale?:THREE.Vector3} )=>{ analysisArray: state.analysisArray }))) - const {shape, dataShape, strides, dimArrays,dimNames,dimUnits} = useGlobalStore( + const {shape, dataShape, strides, dimArrays,dimNames,dimUnits, variable} = useGlobalStore( useShallow(state=>({ shape:state.shape, dataShape: state.dataShape, strides: state.strides, dimArrays:state.dimArrays, dimNames:state.dimNames, - dimUnits:state.dimUnits + dimUnits:state.dimUnits, + variable: state.variable }))) const {selectTS, xRange, yRange, zRange,getColorIdx, incrementColorIdx} = usePlotStore(useShallow(state => ({ @@ -106,7 +107,7 @@ export const UVCube = ( {scale} : {scale?:THREE.Vector3} )=>{ setDimCoords({}); } lastNormal.current = dimAxis; - const tempTS = GetTimeSeries({data: analysisMode ? analysisArray : GetCurrentArray(), shape: dataShape, stride: strides},{uv,normal}) + const tempTS = GetTimeSeries({data: (analysisMode && analysisArray) ? analysisArray : GetCurrentArray(undefined, variable, dataShape, strides), shape: dataShape, stride: strides},{uv,normal}) const plotDim = (normal.toArray()).map((val, idx) => { if (Math.abs(val) > 0) { return idx; diff --git a/src/components/textures/TextureMakers.tsx b/src/components/textures/TextureMakers.tsx index 6fef06c7..e745a9b8 100644 --- a/src/components/textures/TextureMakers.tsx +++ b/src/components/textures/TextureMakers.tsx @@ -8,7 +8,7 @@ interface Array { shape: number[]; } -function StoreData(array: Array, valueScales?: {maxVal: number, minVal: number}): {minVal: number, maxVal: number}{ +function StoreData(array: Array, valueScales?: {maxVal: number, minVal: number}): [{minVal: number, maxVal: number}, Uint8Array]{ const { clampExtremes, setTextureData} = useGlobalStore.getState() const data = array.data; const [minVal,maxVal] = valueScales ? [valueScales.minVal, valueScales.maxVal] : ArrayMinMax(data ) @@ -23,7 +23,7 @@ function StoreData(array: Array, valueScales?: {maxVal: number, minVal: number}) } }; setTextureData(textureData) - return {minVal, maxVal} + return [{minVal, maxVal}, textureData] } export function CreateTexture(shape: number[], data?: Uint8Array) : THREE.DataTexture[] | THREE.Data3DTexture[] | undefined { @@ -75,10 +75,10 @@ export function CreateTexture(shape: number[], data?: Uint8Array) : THREE.DataTe } } -export function ArrayToTexture(array: Array, valueScales?: {maxVal: number, minVal: number}): [ THREE.Data3DTexture[] | THREE.DataTexture[], {minVal: number, maxVal: number}]{ - const scales = StoreData(array, valueScales); +export function ArrayToTexture(array: Array, valueScales?: {maxVal: number, minVal: number}): [ THREE.Data3DTexture[] | THREE.DataTexture[], {minVal: number, maxVal: number}, Uint8Array]{ + const [scales, textureData] = StoreData(array, valueScales); const textures = CreateTexture(array.shape) - return [textures as THREE.Data3DTexture[] | THREE.DataTexture[], scales]; + return [textures as THREE.Data3DTexture[] | THREE.DataTexture[], scales, textureData]; } function chunkArray( diff --git a/src/components/zarr/utils.ts b/src/components/zarr/utils.ts index d02821eb..d3fa361f 100644 --- a/src/components/zarr/utils.ts +++ b/src/components/zarr/utils.ts @@ -191,7 +191,12 @@ export function CompressArray(array: Float16Array, level: number) { // Infer compressed type export function DecompressArray(compressed: Uint8Array) { const decompressed = decompressSync(compressed); - const floatArray = new Float16Array(decompressed.buffer); + const aligned = decompressed.byteOffset % 2 === 0 ? decompressed : decompressed.slice() + const floatArray = new Float16Array( + aligned.buffer, + aligned.byteOffset, + aligned.byteLength / 2, + ); return floatArray; } diff --git a/src/hooks/useDataFetcher.tsx b/src/hooks/useDataFetcher.tsx index 3c89a9f6..184668fc 100644 --- a/src/hooks/useDataFetcher.tsx +++ b/src/hooks/useDataFetcher.tsx @@ -79,7 +79,7 @@ export const useDataFetcher = () => { const activeIndices = result.indices.filter((_, idx) => result.shape[idx] != 1); useGlobalStore.getState().setActiveIndices(activeIndices); - const [tempTexture, scaling] = ArrayToTexture({ + const [tempTexture, scaling, textureData] = ArrayToTexture({ data: result.data, shape }); @@ -87,6 +87,7 @@ export const useDataFetcher = () => { setTextures(tempTexture); setValueScales(scaling as { maxVal: number; minVal: number }); useGlobalStore.getState().setScalingFactor(result.scalingFactor); + useGlobalStore.setState({ textureData }); const shapeLength = shape.length; diff --git a/src/utils/HelperFuncs.ts b/src/utils/HelperFuncs.ts index 63b251af..a86b30f5 100644 --- a/src/utils/HelperFuncs.ts +++ b/src/utils/HelperFuncs.ts @@ -281,15 +281,28 @@ export function GetTimeSeries(array : arrayInfo, TimeSeriesInfo:TimeSeriesInfo){ function DecompressArray(compressed : Uint8Array){ const decompressed = decompressSync(compressed) - const floatArray = new Float16Array(decompressed.buffer) + const aligned = decompressed.byteOffset % 2 === 0 ? decompressed : decompressed.slice() + const floatArray = new Float16Array(aligned.buffer, aligned.byteOffset, aligned.byteLength / 2) return floatArray } -export function GetCurrentArray(overrideStore?:string){ - const { variable, is4D, idx4D, initStore, strides, dataShape, setStatus }= useGlobalStore.getState() +export function GetCurrentArray( + overrideStore?: string, + overrideVariable?: string, + overrideDataShape?: number[], + overrideStrides?: number[] +){ + const { variable: globalVariable, is4D, idx4D, initStore, strides: globalStrides, dataShape: globalDataShape, setStatus }= useGlobalStore.getState() const { arraySize, currentChunks, ndSlices } = useZarrStore.getState() const {cache} = useCacheStore.getState(); const store = overrideStore ? overrideStore : initStore + const variable = overrideVariable ? overrideVariable : globalVariable + const dataShape = overrideDataShape ? overrideDataShape : globalDataShape + const strides = overrideStrides ? overrideStrides : globalStrides + + if (!dataShape || !strides) { + return new Float16Array(0); + } const scalarIndices = (ndSlices && ndSlices.length > 0) ? ndSlices.filter(s => typeof s === "number").join("_") : (idx4D ?? ""); const cacheBase = scalarIndices !== "" ? `${store}_${variable}_${scalarIndices}` : `${store}_${variable}`;