Skip to content

Commit 3593b93

Browse files
authored
Merge pull request #564 from EarthyScience/jp/update-wasm
netcdf4-wasm update. Netcdf INT support.
2 parents bf78f6c + 10b2c29 commit 3593b93

4 files changed

Lines changed: 50 additions & 13 deletions

File tree

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@
4747
"lint": "eslint . --max-warnings=100"
4848
},
4949
"dependencies": {
50-
"@earthyscience/netcdf4-wasm": "^0.1.3",
50+
"@earthyscience/netcdf4-wasm": "0.2.3",
5151
"@ffmpeg/ffmpeg": "^0.12.15",
5252
"@ffmpeg/util": "^0.12.2",
5353
"@monaco-editor/react": "^4.7.0",

src/components/plots/DataCube.tsx

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -73,13 +73,12 @@ export const DataCube = ({ volTexture }: DataCubeProps ) => {
7373
blending: THREE.NormalBlending,
7474
depthWrite: false,
7575
side: useOrtho ? THREE.FrontSide : THREE.BackSide,
76-
}),[useFragOpt, useOrtho]);
76+
}),[useFragOpt, useOrtho, volTexture]);
7777

7878
const geometry = useMemo(() => new THREE.BoxGeometry(shape.x, shape.y, shape.z), [shape]);
7979
useEffect(() => {
8080
if (shaderMaterial) {
8181
const uniforms = shaderMaterial.uniforms
82-
uniforms.map.value = volTexture;
8382
uniforms.cmap.value = colormap;
8483
uniforms.cOffset.value = cOffset;
8584
uniforms.cScale.value = cScale;
@@ -100,7 +99,7 @@ export const DataCube = ({ volTexture }: DataCubeProps ) => {
10099
uniforms.maskValue.value = maskValue
101100
invalidate() // Needed because Won't trigger re-render if camera is stationary.
102101
}
103-
}, [volTexture, shape, colormap, cOffset, cScale, valueRange, xRange, yRange, zRange, aspectRatio, latBounds, lonBounds, quality, animProg, transparency, nanTransparency, nanColor, maskValue, fillValue, vTransferScale, vTransferRange]);
102+
}, [shape, colormap, cOffset, cScale, valueRange, xRange, yRange, zRange, aspectRatio, latBounds, lonBounds, quality, animProg, transparency, nanTransparency, nanColor, maskValue, fillValue, vTransferScale, vTransferRange]);
104103
useFrame(({camera})=>{ // This calculates InverseModel matrix for the orthographic raymarcher
105104
if (!useOrtho || !meshRef.current || !shaderMaterial) return;
106105
meshRef.current.modelViewMatrix.multiplyMatrices(camera.matrixWorldInverse, meshRef.current.matrixWorld);

src/components/zarr/NCGetters.ts

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { useZarrStore, useCacheStore, useGlobalStore, useErrorStore } from "@/GlobalStates"
22
import { ToFloat16, CompressArray, DecompressArray, copyChunkToArray, RescaleArray } from "./ZarrLoaderLRU";
33
import { Convolve } from "../computation/webGPU";
4-
import {coarsen3DArray, calculateStrides} from '@/utils/HelperFuncs'
4+
import {coarsen3DArray, calculateStrides, TypedArray} from '@/utils/HelperFuncs'
55

66
export async function GetNCDims(variable: string){
77
const {ncModule} = useZarrStore.getState()
@@ -67,6 +67,18 @@ export async function GetNCArray(variable: string){
6767
if ("_FillValue" in atts){
6868
fillValue = !Number.isNaN(atts["_FillValue"][0]) ? atts["_FillValue"][0] : fillValue
6969
}
70+
let validRange: {min: number, max: number} | undefined;
71+
if("valid_min" in atts && "valid_max" in atts){
72+
validRange = {
73+
min: atts["valid_min"][0],
74+
max: atts["valid_max"][0]
75+
}
76+
}
77+
let preScaling: number | undefined;
78+
if ("scale_factor" in atts){
79+
const thisScale = atts["scale_factor"][0]
80+
if (thisScale != 1) preScaling = thisScale
81+
}
7082

7183
//---- Dimension Indices to Grab ----//
7284
const calcDim = (slice: [number, number | null], dimIdx: number) => {
@@ -169,12 +181,37 @@ export async function GetNCArray(variable: string){
169181
return {starts, counts}
170182
}
171183
const { starts, counts } = getStartsAndCounts();
172-
const chunkArray = await ncModule.getSlicedVariableArray(variable, starts, counts)
184+
let chunkArray = await ncModule.getSlicedVariableArray(variable, starts, counts)
185+
const chunkType = chunkArray.constructor.name
186+
const isInt = chunkType.includes("int")
173187
let chunkStride = rank > 3
174188
? [counts[3] * counts[2], counts[3], 1]
175189
: [counts[2] * counts[1], counts[2], 1]
176190
let thisShape = counts
177-
let [chunkF16, newScalingFactor] = ToFloat16(chunkArray.map((v: number) => v === fillValue ? NaN : v), scalingFactor)
191+
const filterValues = (array: TypedArray) =>{
192+
for (let i = 0; i < array.length; i++){
193+
if (array[i] === fillValue && !isInt) array[i] = NaN
194+
if (validRange){
195+
if (isInt){
196+
if (array[i] < validRange.min) array[i] = validRange.min
197+
if (array[i] > validRange.max) array[i] = validRange.max
198+
} else{
199+
if (array[i] < validRange.min || array[i] > validRange.max) array[i] = NaN
200+
}
201+
202+
}
203+
}
204+
}
205+
const preScale = (array: TypedArray, scaler: number) =>{
206+
const tempArray = new Float32Array(array.length);
207+
for (let i = 0; i < array.length; i++){
208+
tempArray[i] = array[i] * scaler;
209+
}
210+
return tempArray;
211+
}
212+
filterValues(chunkArray)
213+
if (preScaling) chunkArray = preScale(chunkArray, preScaling)
214+
let [chunkF16, newScalingFactor] = ToFloat16(chunkArray, scalingFactor)
178215
if (coarsen){
179216
chunkF16 = await Convolve(chunkF16, {shape:chunkShape, strides:chunkStride}, "Mean3D", {kernelSize, kernelDepth}) as Float16Array
180217
thisShape = thisShape.map((dim: number, idx: number) => Math.floor(dim / (idx === 0 ? kernelDepth : kernelSize)))

src/components/zarr/ZarrLoaderLRU.ts

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,16 +21,17 @@ export function ToFloat16(array : Float32Array, scalingFactor: number | null) :
2121
array[i] /= Math.pow(10,scalingFactor);
2222
}
2323
}
24-
const [minVal, maxVal] = ArrayMinMax(array)
25-
if (maxVal <= 65504 && minVal >= -65504 && Math.abs(maxVal) > 1e-3 ){ // If values fit in Float16, use that to save memory
26-
newArray = new Float16Array(array)
27-
}
28-
else {
29-
newScalingFactor = Math.ceil(Math.log10(maxVal/65504))
24+
const maxVal = array.reduce((max, val) => Math.max(max, Math.abs(val)), -Infinity)
25+
newScalingFactor = Math.ceil(Math.log10(maxVal/65504))
26+
if (newScalingFactor > 1 || newScalingFactor < -8){
27+
newScalingFactor = newScalingFactor + (scalingFactor ?? 0)
3028
for (let i = 0; i < array.length; i++) {
3129
array[i] /= Math.pow(10,newScalingFactor);
3230
}
3331
newArray = new Float16Array(array)
32+
} else{
33+
newArray = new Float16Array(array)
34+
newScalingFactor = scalingFactor
3435
}
3536
return [newArray, newScalingFactor]
3637
}

0 commit comments

Comments
 (0)