mirror of
https://github.com/chanzuckerberg/cellxgene.git
synced 2026-10-03 03:08:12 +08:00
Dataframe (#576)
* initial dataframe commit * initial dataframe port of core app * rename variables for clarity * remove unused import * comment out unused code * fix array handling bug in crossfilter dimension creation * allow creation of empty dataframes * handle non-existent columns * handle non-existent columns * revise tests for new dataframe * comments for clarity * comments for clarity * generate bulk add placeholder with real gene names * fix bug in gene name adding * more dataframe unit tests * fix bug - subset from current world, not universe * put cut and pasted code into a single function * improve caching of crossfilter * remove cascading update bug from graph * more performance work * improve state handling for scatterplot * performance optimization of critical path * add column summarization * dataframe utils * add callOnceLazy * fix tests * minor updates found during review * fix misspelling * remove RESTv02 from function names * comment cleanup * cut/icut col parameter defaults to null * break up large test * improve tests and comments on dataframe at/has functions
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import _ from "lodash";
|
||||
import * as Universe from "../../../src/util/stateManager/universe";
|
||||
import * as World from "../../../src/util/stateManager/world";
|
||||
import * as Dataframe from "../../../src/util/dataframe";
|
||||
import Crossfilter from "../../../src/util/typedCrossfilter";
|
||||
import * as REST from "./sampleResponses";
|
||||
import {
|
||||
@@ -16,7 +17,7 @@ the default REST test response.
|
||||
const defaultBigBang = () => {
|
||||
/* create unverse, world, crossfilter and dimensionMap */
|
||||
/* create universe */
|
||||
const universe = Universe.createUniverseFromRestV02Response(
|
||||
const universe = Universe.createUniverseFromResponse(
|
||||
REST.config,
|
||||
REST.schema,
|
||||
REST.annotationsObs,
|
||||
@@ -40,7 +41,7 @@ const defaultBigBang = () => {
|
||||
|
||||
describe("createWorldFromEntireUniverse", () => {
|
||||
test("create from REST sample", () => {
|
||||
const universe = Universe.createUniverseFromRestV02Response(
|
||||
const universe = Universe.createUniverseFromResponse(
|
||||
REST.config,
|
||||
REST.schema,
|
||||
REST.annotationsObs,
|
||||
@@ -75,10 +76,7 @@ describe("createWorldFromEntireUniverse", () => {
|
||||
.value()
|
||||
}),
|
||||
|
||||
varDataCache: expect.any(Object),
|
||||
|
||||
obsIndex: null, // null indicating full universe
|
||||
obsBackIndex: null
|
||||
varDataCache: expect.any(Object)
|
||||
})
|
||||
);
|
||||
});
|
||||
@@ -111,51 +109,43 @@ describe("createWorldFromCurrentSelection", () => {
|
||||
*/
|
||||
|
||||
/* matchFilter must match the dimension filters above */
|
||||
const matchFilter = val => val.field1 >= 0 && val.field1 < 5 && !val.field3;
|
||||
const universeIndices = _()
|
||||
.range(universe.nObs)
|
||||
.filter(idx => matchFilter(universe.obsAnnotations[idx]))
|
||||
.value();
|
||||
|
||||
const expected = {
|
||||
nObs: universeIndices.length,
|
||||
obsAnnotations: _.map(universeIndices, i => universe.obsAnnotations[i]),
|
||||
obsLayout: {
|
||||
X: new Float32Array(
|
||||
_.map(universeIndices, i => universe.obsLayout.X[i])
|
||||
),
|
||||
Y: new Float32Array(
|
||||
_.map(universeIndices, i => universe.obsLayout.Y[i])
|
||||
)
|
||||
},
|
||||
obsBackIndex: _.transform(
|
||||
universeIndices,
|
||||
(result, univIdx, worldIdx) => {
|
||||
result[univIdx] = worldIdx;
|
||||
},
|
||||
new Uint32Array(universe.nObs).fill(-1)
|
||||
),
|
||||
obsIndex: new Uint32Array(universeIndices)
|
||||
const matchFilter = (df, row) => {
|
||||
const field1 = df.at(row, "field1");
|
||||
const field3 = df.at(row, "field3");
|
||||
return field1 >= 0 && field1 < 5 && !field3;
|
||||
};
|
||||
const matchingIndices = _()
|
||||
.range(universe.nObs)
|
||||
.filter(idx => matchFilter(universe.obsAnnotations, idx))
|
||||
.value();
|
||||
|
||||
expect(world).toMatchObject(
|
||||
expect.objectContaining({
|
||||
api: "0.2",
|
||||
nObs: expected.nObs,
|
||||
nObs: matchingIndices.length,
|
||||
nVar: universe.nVar,
|
||||
schema: universe.schema,
|
||||
obsAnnotations: expected.obsAnnotations,
|
||||
obsAnnotations: expect.any(Dataframe.Dataframe),
|
||||
varAnnotations: universe.varAnnotations,
|
||||
obsLayout: expected.obsLayout,
|
||||
obsLayout: expect.any(Dataframe.Dataframe),
|
||||
summary: {
|
||||
obs: expect.any(Object) /* we could do better! */,
|
||||
var: expect.any(Object) /* we could do better! */
|
||||
},
|
||||
varDataCache: expect.any(Object),
|
||||
obsIndex: expected.obsIndex,
|
||||
obsBackIndex: expected.obsBackIndex
|
||||
varDataCache: expect.any(Object)
|
||||
})
|
||||
);
|
||||
|
||||
expect(world.obsAnnotations.rowIndex.keys()).toEqual(
|
||||
new Int32Array(matchingIndices)
|
||||
);
|
||||
expect(world.obsAnnotations.colIndex.keys()).toEqual(
|
||||
universe.obsAnnotations.colIndex.keys()
|
||||
);
|
||||
expect(world.obsLayout.rowIndex.keys()).toEqual(
|
||||
new Int32Array(matchingIndices)
|
||||
);
|
||||
expect(world.obsLayout.colIndex.keys()).toEqual(["X", "Y"]);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -219,7 +209,9 @@ describe("subsetVarData", () => {
|
||||
world,
|
||||
crossfilter
|
||||
);
|
||||
expect(newWorld.obsIndex).toMatchObject(new Uint32Array([0, 2]));
|
||||
expect(newWorld.obsAnnotations.rowIndex.keys()).toEqual(
|
||||
new Int32Array([0, 2])
|
||||
);
|
||||
|
||||
/* expect a subset */
|
||||
const result = World.subsetVarData(newWorld, universe, sourceVarData);
|
||||
|
||||
Reference in New Issue
Block a user