mirror of
https://github.com/chanzuckerberg/cellxgene.git
synced 2026-10-05 08:38:12 +08:00
add array type foundations (#2376)
This commit is contained in:
@@ -8,7 +8,7 @@ import {
|
|||||||
removeObsAnnoCategory,
|
removeObsAnnoCategory,
|
||||||
addObsLayout,
|
addObsLayout,
|
||||||
} from "../util/stateManager/schemaHelpers";
|
} from "../util/stateManager/schemaHelpers";
|
||||||
import { isArrayOrTypedArray } from "../util/typeHelpers";
|
import { isAnyArray } from "../common/types/arraytypes";
|
||||||
import { _whereCacheCreate } from "./whereCache";
|
import { _whereCacheCreate } from "./whereCache";
|
||||||
import AnnoMatrix from "./annoMatrix";
|
import AnnoMatrix from "./annoMatrix";
|
||||||
import PromiseLimit from "../util/promiseLimit";
|
import PromiseLimit from "../util/promiseLimit";
|
||||||
@@ -134,7 +134,7 @@ export default class AnnoMatrixLoader extends AnnoMatrix {
|
|||||||
|
|
||||||
const newAnnoMatrix = this._clone();
|
const newAnnoMatrix = this._clone();
|
||||||
let data;
|
let data;
|
||||||
if (isArrayOrTypedArray(value)) {
|
if (isAnyArray(value)) {
|
||||||
if (value.constructor !== Ctor)
|
if (value.constructor !== Ctor)
|
||||||
throw new Error("Mismatched value array type");
|
throw new Error("Mismatched value array type");
|
||||||
if (value.length !== this.nObs)
|
if (value.length !== this.nObs)
|
||||||
|
|||||||
@@ -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";
|
import { IdentityInt32Index, isLabelIndex } from "./labelIndex";
|
||||||
// weird cross-dependency that we should clean up someday...
|
// weird cross-dependency that we should clean up someday...
|
||||||
import {
|
import { callOnceLazy, memoize, __getMemoId } from "./util";
|
||||||
isTypedArray,
|
import { isTypedArray, isAnyArray } from "../../common/types/arraytypes";
|
||||||
isArrayOrTypedArray,
|
|
||||||
callOnceLazy,
|
|
||||||
memoize,
|
|
||||||
__getMemoId,
|
|
||||||
} from "./util";
|
|
||||||
import {
|
import {
|
||||||
summarizeContinuous,
|
summarizeContinuous,
|
||||||
summarizeCategorical as _summarizeCategorical,
|
summarizeCategorical as _summarizeCategorical,
|
||||||
@@ -163,7 +158,7 @@ class Dataframe {
|
|||||||
if (!Array.isArray(columnarData)) {
|
if (!Array.isArray(columnarData)) {
|
||||||
throw new TypeError("Dataframe constructor requires array of columns");
|
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");
|
throw new TypeError("Dataframe columns must all be Array or TypedArray");
|
||||||
}
|
}
|
||||||
if (!isLabelIndex(rowIndex)) {
|
if (!isLabelIndex(rowIndex)) {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
Dataframe histogram
|
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.
|
// 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) {
|
function _histogramContinuous(column: any, bins: any, min: any, max: any) {
|
||||||
|
|||||||
@@ -2,8 +2,6 @@
|
|||||||
Private utility code for dataframe
|
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.
|
// 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) {
|
export function callOnceLazy(f: any) {
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { flatbuffers } from "flatbuffers";
|
import { flatbuffers } from "flatbuffers";
|
||||||
import { NetEncoding } from "./matrix_generated";
|
import { NetEncoding } from "./matrix_generated";
|
||||||
import { isTypedArray, isFpTypedArray } from "../typeHelpers";
|
import { isTypedArray, isFloatTypedArray } from "../../common/types/arraytypes";
|
||||||
import {
|
import {
|
||||||
Dataframe,
|
Dataframe,
|
||||||
IdentityInt32Index,
|
IdentityInt32Index,
|
||||||
@@ -188,7 +188,7 @@ function promoteTypedArray(o: any) {
|
|||||||
TODO - future optimization: not all int32/uint32 data series require
|
TODO - future optimization: not all int32/uint32 data series require
|
||||||
promotion to float64. We COULD simply look at the data to decide.
|
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;
|
let TypedArrayCtor;
|
||||||
switch (o.constructor) {
|
switch (o.constructor) {
|
||||||
@@ -246,7 +246,7 @@ export function matrixFBSToDataframe(arrayBuffers: any) {
|
|||||||
.map((fb: any) =>
|
.map((fb: any) =>
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any --- FIXME: disabled temporarily on migrate to TS.
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any --- FIXME: disabled temporarily on migrate to TS.
|
||||||
fb.columns.map((c: any) => {
|
fb.columns.map((c: any) => {
|
||||||
if (isFpTypedArray(c) || Array.isArray(c)) return c;
|
if (isFloatTypedArray(c) || Array.isArray(c)) return c;
|
||||||
return promoteTypedArray(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,
|
upperBoundIndirect,
|
||||||
} from "./sort";
|
} from "./sort";
|
||||||
import { makeSortIndex } from "./util";
|
import { makeSortIndex } from "./util";
|
||||||
|
import { isAnyArray } from "../../common/types/arraytypes";
|
||||||
|
|
||||||
class NotImplementedError extends Error {
|
class NotImplementedError extends Error {
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any --- FIXME: disabled temporarily on migrate to TS.
|
// 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,
|
value,
|
||||||
new ValueArrayType(data.length)
|
new ValueArrayType(data.length)
|
||||||
);
|
);
|
||||||
} else if (isArrayOrTypedArray(value)) {
|
} else if (isAnyArray(value)) {
|
||||||
// Create value array from user-provided array. Typically used
|
// Create value array from user-provided array. Typically used
|
||||||
// only by enumerated dimensions
|
// only by enumerated dimensions
|
||||||
array = this._createValueArray(
|
array = this._createValueArray(
|
||||||
@@ -729,15 +730,6 @@ export const DimTypes = {
|
|||||||
spatial: ImmutableSpatialDimension,
|
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 */
|
/* return bounding box of the polygon */
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any --- FIXME: disabled temporarily on migrate to TS.
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any --- FIXME: disabled temporarily on migrate to TS.
|
||||||
function polygonBoundingBox(polygon: any) {
|
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 */
|
/* 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);
|
return quicksort(arr, 0, arr.length - 1);
|
||||||
}
|
}
|
||||||
if (isTypedArray(arr)) {
|
if (isTypedArray(arr)) {
|
||||||
if (isFpTypedArray(arr)) {
|
if (isFloatTypedArray(arr)) {
|
||||||
return quicksortFloats(arr, 0, arr.length - 1);
|
return quicksortFloats(arr, 0, arr.length - 1);
|
||||||
}
|
}
|
||||||
return quicksort(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.
|
// 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) {
|
export function sortIndex(index: any, source: any) {
|
||||||
if (isFpTypedArray(source))
|
if (isFloatTypedArray(source))
|
||||||
return quicksortFloatsIndirect(index, source, 0, index.length - 1);
|
return quicksortFloatsIndirect(index, source, 0, index.length - 1);
|
||||||
return quicksortIndirect(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.
|
// 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) {
|
export function lowerBound(valueArray: any, value: any, first: any, last: any) {
|
||||||
if (isFpTypedArray(valueArray)) {
|
if (isFloatTypedArray(valueArray)) {
|
||||||
return lowerBoundFloat(valueArray, value, first, last);
|
return lowerBoundFloat(valueArray, value, first, last);
|
||||||
}
|
}
|
||||||
return lowerBoundNonFloat(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.
|
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any -- - FIXME: disabled temporarily on migrate to TS.
|
||||||
last: any
|
last: any
|
||||||
) {
|
) {
|
||||||
if (isFpTypedArray(valueArray)) {
|
if (isFloatTypedArray(valueArray)) {
|
||||||
return lowerBoundFloatIndirect(valueArray, indexArray, value, first, last);
|
return lowerBoundFloatIndirect(valueArray, indexArray, value, first, last);
|
||||||
}
|
}
|
||||||
return lowerBoundNonFloatIndirect(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.
|
// 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) {
|
export function upperBound(valueArray: any, value: any, first: any, last: any) {
|
||||||
if (isFpTypedArray(valueArray)) {
|
if (isFloatTypedArray(valueArray)) {
|
||||||
return upperBoundFloat(valueArray, value, first, last);
|
return upperBoundFloat(valueArray, value, first, last);
|
||||||
}
|
}
|
||||||
return upperBoundNonFloat(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.
|
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any -- - FIXME: disabled temporarily on migrate to TS.
|
||||||
last: any
|
last: any
|
||||||
) {
|
) {
|
||||||
if (isFpTypedArray(valueArray)) {
|
if (isFloatTypedArray(valueArray)) {
|
||||||
return upperBoundFloatIndirect(valueArray, indexArray, value, first, last);
|
return upperBoundFloatIndirect(valueArray, indexArray, value, first, last);
|
||||||
}
|
}
|
||||||
return upperBoundNonFloatIndirect(valueArray, indexArray, value, first, last);
|
return upperBoundNonFloatIndirect(valueArray, indexArray, value, first, last);
|
||||||
|
|||||||
Reference in New Issue
Block a user