|
1 | 1 | import { useZarrStore, useCacheStore, useGlobalStore, useErrorStore } from "@/GlobalStates" |
2 | 2 | import { ToFloat16, CompressArray, DecompressArray, copyChunkToArray, RescaleArray } from "./ZarrLoaderLRU"; |
3 | 3 | import { Convolve } from "../computation/webGPU"; |
4 | | -import {coarsen3DArray, calculateStrides} from '@/utils/HelperFuncs' |
| 4 | +import {coarsen3DArray, calculateStrides, TypedArray} from '@/utils/HelperFuncs' |
5 | 5 |
|
6 | 6 | export async function GetNCDims(variable: string){ |
7 | 7 | const {ncModule} = useZarrStore.getState() |
@@ -67,6 +67,18 @@ export async function GetNCArray(variable: string){ |
67 | 67 | if ("_FillValue" in atts){ |
68 | 68 | fillValue = !Number.isNaN(atts["_FillValue"][0]) ? atts["_FillValue"][0] : fillValue |
69 | 69 | } |
| 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 | + } |
70 | 82 |
|
71 | 83 | //---- Dimension Indices to Grab ----// |
72 | 84 | const calcDim = (slice: [number, number | null], dimIdx: number) => { |
@@ -169,12 +181,37 @@ export async function GetNCArray(variable: string){ |
169 | 181 | return {starts, counts} |
170 | 182 | } |
171 | 183 | 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") |
173 | 187 | let chunkStride = rank > 3 |
174 | 188 | ? [counts[3] * counts[2], counts[3], 1] |
175 | 189 | : [counts[2] * counts[1], counts[2], 1] |
176 | 190 | 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) |
178 | 215 | if (coarsen){ |
179 | 216 | chunkF16 = await Convolve(chunkF16, {shape:chunkShape, strides:chunkStride}, "Mean3D", {kernelSize, kernelDepth}) as Float16Array |
180 | 217 | thisShape = thisShape.map((dim: number, idx: number) => Math.floor(dim / (idx === 0 ? kernelDepth : kernelSize))) |
|
0 commit comments