mirror of
https://github.com/chanzuckerberg/cellxgene.git
synced 2026-09-19 10:58:10 +08:00
add array type foundations (#2376)
This commit is contained in:
@@ -8,7 +8,7 @@ import {
|
||||
removeObsAnnoCategory,
|
||||
addObsLayout,
|
||||
} from "../util/stateManager/schemaHelpers";
|
||||
import { isArrayOrTypedArray } from "../util/typeHelpers";
|
||||
import { isAnyArray } from "../common/types/arraytypes";
|
||||
import { _whereCacheCreate } from "./whereCache";
|
||||
import AnnoMatrix from "./annoMatrix";
|
||||
import PromiseLimit from "../util/promiseLimit";
|
||||
@@ -134,7 +134,7 @@ export default class AnnoMatrixLoader extends AnnoMatrix {
|
||||
|
||||
const newAnnoMatrix = this._clone();
|
||||
let data;
|
||||
if (isArrayOrTypedArray(value)) {
|
||||
if (isAnyArray(value)) {
|
||||
if (value.constructor !== Ctor)
|
||||
throw new Error("Mismatched value array type");
|
||||
if (value.length !== this.nObs)
|
||||
|
||||
85
client/src/common/types/arraytypes.ts
Normal file
85
client/src/common/types/arraytypes.ts
Normal file
@@ -0,0 +1,85 @@
|
||||
/**
|
||||
* Utility type and interface definitions.
|
||||
*/
|
||||
|
||||
/**
|
||||
* TypedArrays that can be assigned to a number.
|
||||
*/
|
||||
export type TypedArray =
|
||||
| Int8Array
|
||||
| Uint8Array
|
||||
| Int16Array
|
||||
| Uint16Array
|
||||
| Int32Array
|
||||
| Uint32Array
|
||||
| Float32Array
|
||||
| Float64Array;
|
||||
|
||||
export type UnsignedTypedArray = Uint8Array | Uint16Array | Uint32Array;
|
||||
export type FloatTypedArray = Float32Array | Float64Array;
|
||||
|
||||
export type TypedArrayConstructor =
|
||||
| Int8ArrayConstructor
|
||||
| Uint8ArrayConstructor
|
||||
| Int16ArrayConstructor
|
||||
| Uint16ArrayConstructor
|
||||
| Int32ArrayConstructor
|
||||
| Uint32ArrayConstructor
|
||||
| Float32ArrayConstructor
|
||||
| Float64ArrayConstructor;
|
||||
|
||||
export type AnyArray = Array<unknown> | TypedArray;
|
||||
|
||||
export type NumberArray = Array<number> | TypedArray;
|
||||
|
||||
export type Int8 = Int8Array[0];
|
||||
export type Uint8 = Uint8Array[0];
|
||||
export type Int16 = Int16Array[0];
|
||||
export type Uint16 = Uint16Array[0];
|
||||
export type Int32 = Int32Array[0];
|
||||
export type Uint32 = Uint32Array[0];
|
||||
export type Float32 = Float32Array[0];
|
||||
export type Float64 = Float64Array[0];
|
||||
|
||||
/**
|
||||
* Test if the parameter is a TypedArray.
|
||||
* @param tbd - value to be tested
|
||||
* @returns true if `tbd` is a TypedArray, false if not.
|
||||
*/
|
||||
export function isTypedArray(tbd: unknown): tbd is TypedArray {
|
||||
return (
|
||||
ArrayBuffer.isView(tbd) &&
|
||||
Object.prototype.toString.call(tbd) !== "[object DataView]"
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if the paramter is a float TypedArray
|
||||
* @param tbd - value to be tested
|
||||
* @returns - true if `tbd` is a float typed array.
|
||||
*/
|
||||
export function isFloatTypedArray(tbd: unknown): tbd is FloatTypedArray {
|
||||
return tbd instanceof Float32Array || tbd instanceof Float64Array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if the paramter is a float TypedArray
|
||||
* @param tbd - value to be tested
|
||||
* @returns - true if `tbd` is a float typed array.
|
||||
*/
|
||||
export function isUnsignedTypedArray(tbd: unknown): tbd is UnsignedTypedArray {
|
||||
return (
|
||||
tbd instanceof Uint8Array ||
|
||||
tbd instanceof Uint16Array ||
|
||||
tbd instanceof Uint32Array
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if the parameter is a TypedArray or Array
|
||||
* @param tbd - value to be tested
|
||||
* @returns - true if `tbd` is a TypedArray or Array
|
||||
*/
|
||||
export function isAnyArray(tbd: unknown): tbd is AnyArray {
|
||||
return Array.isArray(tbd) || isTypedArray(tbd);
|
||||
}
|
||||
@@ -1,12 +1,7 @@
|
||||
import { IdentityInt32Index, isLabelIndex } from "./labelIndex";
|
||||
// weird cross-dependency that we should clean up someday...
|
||||
import {
|
||||
isTypedArray,
|
||||
isArrayOrTypedArray,
|
||||
callOnceLazy,
|
||||
memoize,
|
||||
__getMemoId,
|
||||
} from "./util";
|
||||
import { callOnceLazy, memoize, __getMemoId } from "./util";
|
||||
import { isTypedArray, isAnyArray } from "../../common/types/arraytypes";
|
||||
import {
|
||||
summarizeContinuous,
|
||||
summarizeCategorical as _summarizeCategorical,
|
||||
@@ -163,7 +158,7 @@ class Dataframe {
|
||||
if (!Array.isArray(columnarData)) {
|
||||
throw new TypeError("Dataframe constructor requires array of columns");
|
||||
}
|
||||
if (!columnarData.every((c) => isArrayOrTypedArray(c))) {
|
||||
if (!columnarData.every((c) => isAnyArray(c))) {
|
||||
throw new TypeError("Dataframe columns must all be Array or TypedArray");
|
||||
}
|
||||
if (!isLabelIndex(rowIndex)) {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
Dataframe histogram
|
||||
*/
|
||||
import { isTypedArray } from "./util";
|
||||
import { isTypedArray } from "../../common/types/arraytypes";
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any --- FIXME: disabled temporarily on migrate to TS.
|
||||
function _histogramContinuous(column: any, bins: any, min: any, max: any) {
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
Private utility code for dataframe
|
||||
*/
|
||||
|
||||
export { isTypedArray, isArrayOrTypedArray } from "../typeHelpers";
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any -- - FIXME: disabled temporarily on migrate to TS.
|
||||
export function callOnceLazy(f: any) {
|
||||
/*
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { flatbuffers } from "flatbuffers";
|
||||
import { NetEncoding } from "./matrix_generated";
|
||||
import { isTypedArray, isFpTypedArray } from "../typeHelpers";
|
||||
import { isTypedArray, isFloatTypedArray } from "../../common/types/arraytypes";
|
||||
import {
|
||||
Dataframe,
|
||||
IdentityInt32Index,
|
||||
@@ -188,7 +188,7 @@ function promoteTypedArray(o: any) {
|
||||
TODO - future optimization: not all int32/uint32 data series require
|
||||
promotion to float64. We COULD simply look at the data to decide.
|
||||
*/
|
||||
if (isFpTypedArray(o) || Array.isArray(o)) return o;
|
||||
if (isFloatTypedArray(o) || Array.isArray(o)) return o;
|
||||
|
||||
let TypedArrayCtor;
|
||||
switch (o.constructor) {
|
||||
@@ -246,7 +246,7 @@ export function matrixFBSToDataframe(arrayBuffers: any) {
|
||||
.map((fb: any) =>
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any --- FIXME: disabled temporarily on migrate to TS.
|
||||
fb.columns.map((c: any) => {
|
||||
if (isFpTypedArray(c) || Array.isArray(c)) return c;
|
||||
if (isFloatTypedArray(c) || Array.isArray(c)) return c;
|
||||
return promoteTypedArray(c);
|
||||
})
|
||||
)
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
/*
|
||||
Various type and schema related helper functions.
|
||||
*/
|
||||
|
||||
/*
|
||||
Utility function to test for a typed array
|
||||
*/
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any -- - FIXME: disabled temporarily on migrate to TS.
|
||||
export function isTypedArray(x: any) {
|
||||
return (
|
||||
ArrayBuffer.isView(x) &&
|
||||
Object.prototype.toString.call(x) !== "[object DataView]"
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
Test for float typed array, ie, Float32TypedArray or Float64TypedArray
|
||||
*/
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any -- - FIXME: disabled temporarily on migrate to TS.
|
||||
export function isFpTypedArray(x: any) {
|
||||
let constructor;
|
||||
const isFloatArray =
|
||||
x &&
|
||||
({ constructor } = x) &&
|
||||
(constructor === Float32Array || constructor === Float64Array);
|
||||
return isFloatArray;
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any -- - FIXME: disabled temporarily on migrate to TS.
|
||||
export function isArrayOrTypedArray(x: any) {
|
||||
return Array.isArray(x) || isTypedArray(x);
|
||||
}
|
||||
@@ -9,6 +9,7 @@ import {
|
||||
upperBoundIndirect,
|
||||
} from "./sort";
|
||||
import { makeSortIndex } from "./util";
|
||||
import { isAnyArray } from "../../common/types/arraytypes";
|
||||
|
||||
class NotImplementedError extends Error {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any --- FIXME: disabled temporarily on migrate to TS.
|
||||
@@ -450,7 +451,7 @@ class ImmutableScalarDimension extends _ImmutableBaseDimension {
|
||||
value,
|
||||
new ValueArrayType(data.length)
|
||||
);
|
||||
} else if (isArrayOrTypedArray(value)) {
|
||||
} else if (isAnyArray(value)) {
|
||||
// Create value array from user-provided array. Typically used
|
||||
// only by enumerated dimensions
|
||||
array = this._createValueArray(
|
||||
@@ -729,15 +730,6 @@ export const DimTypes = {
|
||||
spatial: ImmutableSpatialDimension,
|
||||
};
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any --- FIXME: disabled temporarily on migrate to TS.
|
||||
function isArrayOrTypedArray(x: any) {
|
||||
return (
|
||||
Array.isArray(x) ||
|
||||
(ArrayBuffer.isView(x) &&
|
||||
Object.prototype.toString.call(x) !== "[object DataView]")
|
||||
);
|
||||
}
|
||||
|
||||
/* return bounding box of the polygon */
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any --- FIXME: disabled temporarily on migrate to TS.
|
||||
function polygonBoundingBox(polygon: any) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { isTypedArray, isFpTypedArray } from "../typeHelpers";
|
||||
import { isTypedArray, isFloatTypedArray } from "../../common/types/arraytypes";
|
||||
|
||||
/* eslint-disable no-bitwise -- code relies on bitwise ops */
|
||||
|
||||
@@ -219,7 +219,7 @@ export function sortArray(arr: any) {
|
||||
return quicksort(arr, 0, arr.length - 1);
|
||||
}
|
||||
if (isTypedArray(arr)) {
|
||||
if (isFpTypedArray(arr)) {
|
||||
if (isFloatTypedArray(arr)) {
|
||||
return quicksortFloats(arr, 0, arr.length - 1);
|
||||
}
|
||||
return quicksort(arr, 0, arr.length - 1);
|
||||
@@ -230,7 +230,7 @@ export function sortArray(arr: any) {
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any -- - FIXME: disabled temporarily on migrate to TS.
|
||||
export function sortIndex(index: any, source: any) {
|
||||
if (isFpTypedArray(source))
|
||||
if (isFloatTypedArray(source))
|
||||
return quicksortFloatsIndirect(index, source, 0, index.length - 1);
|
||||
return quicksortIndirect(index, source, 0, index.length - 1);
|
||||
}
|
||||
@@ -293,7 +293,7 @@ function lowerBoundFloat(valueArray: any, value: any, first: any, last: any) {
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any -- - FIXME: disabled temporarily on migrate to TS.
|
||||
export function lowerBound(valueArray: any, value: any, first: any, last: any) {
|
||||
if (isFpTypedArray(valueArray)) {
|
||||
if (isFloatTypedArray(valueArray)) {
|
||||
return lowerBoundFloat(valueArray, value, first, last);
|
||||
}
|
||||
return lowerBoundNonFloat(valueArray, value, first, last);
|
||||
@@ -366,7 +366,7 @@ export function lowerBoundIndirect(
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any -- - FIXME: disabled temporarily on migrate to TS.
|
||||
last: any
|
||||
) {
|
||||
if (isFpTypedArray(valueArray)) {
|
||||
if (isFloatTypedArray(valueArray)) {
|
||||
return lowerBoundFloatIndirect(valueArray, indexArray, value, first, last);
|
||||
}
|
||||
return lowerBoundNonFloatIndirect(valueArray, indexArray, value, first, last);
|
||||
@@ -425,7 +425,7 @@ function upperBoundFloat(valueArray: any, value: any, first: any, last: any) {
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any -- - FIXME: disabled temporarily on migrate to TS.
|
||||
export function upperBound(valueArray: any, value: any, first: any, last: any) {
|
||||
if (isFpTypedArray(valueArray)) {
|
||||
if (isFloatTypedArray(valueArray)) {
|
||||
return upperBoundFloat(valueArray, value, first, last);
|
||||
}
|
||||
return upperBoundNonFloat(valueArray, value, first, last);
|
||||
@@ -498,7 +498,7 @@ export function upperBoundIndirect(
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any -- - FIXME: disabled temporarily on migrate to TS.
|
||||
last: any
|
||||
) {
|
||||
if (isFpTypedArray(valueArray)) {
|
||||
if (isFloatTypedArray(valueArray)) {
|
||||
return upperBoundFloatIndirect(valueArray, indexArray, value, first, last);
|
||||
}
|
||||
return upperBoundNonFloatIndirect(valueArray, indexArray, value, first, last);
|
||||
|
||||
Reference in New Issue
Block a user