Files
cellxgene/client/src/annoMatrix/views.js
Bruce Martin eaae6df5e3 TS Revert (1) (#2402)
* revert all commits to before Typescript migration

* update compat workflow to match latest deps (#2335)

* update compat workflow to match latest deps

* attempt to debug

* attempt to debug

* remove debugging code

* typo

* update deps to match desktop (#2340)

* fix: don't run lint with `--fix` on push tests (#2273)

* fix: don't run lint with `--fix` on push tests

* npx

Co-authored-by: maniarathi <mani.arathi@gmail.com>
Co-authored-by: Madison Dunitz <madison.dunitz@chanzuckerberg.com>

* rename X_approx_distribution to X_approximate_distribution (#2337)

* Correctly handle non-finite numbers in heuristic determination of X distribution (#2342)

* handle non-finites explicitly

* improve and test edge case handling for distribution estimation

* revert debugging changes

* code readability

* clean up type inferencing (#2332)

* unit tests for 64 bit conversion

* clean up type handling

* type inference tests

* more type inference fixes

* use schema to determine user intent for data typing

* stop using deprecated API

* fbs type encoding test

* add missing test

* add more tests

* correctly infer X type for CXG adaptor

* lint

* fix typo

* ts migration

* cleanup from PR review

* lint

* PR review changes

* remove unused packages from client (#2359)

* remove unused packages from client

* add missing peer dep

* fix: disable FE auth testing on compatibility tests (#2377)

* update: release process (#2277)

Co-authored-by: maniarathi <mani.arathi@gmail.com>

* fix: remove spaces in param setup (#2380)

* delete deploy workflow (#2396)

* undo reformatting which now does not pass lint

* fix snapshots which changed due to npm dep changes

* add missing quoting to snapshot

* another snapshot typo fix

* TS Revert (2) - replay PR #2347 and #2354 (#2403)

* replay edits from PR 2347

* TS Revert (3) - replay edits in PR #2327 (#2404)

* replay edits in PR 2327

* TS Revert (4) - replay PR #2355 (#2405)

* replay edits in PR 2355

* add additional babel config

* reformat with new prettier config

Co-authored-by: Severiano Badajoz <sbadajoz@chanzuckerberg.com>
Co-authored-by: maniarathi <mani.arathi@gmail.com>
Co-authored-by: Madison Dunitz <madison.dunitz@chanzuckerberg.com>
2021-08-23 15:01:36 -07:00

177 lines
5.1 KiB
JavaScript

/* eslint-disable max-classes-per-file -- Classes are interrelated*/
/*
Views on the annomatrix. all API here is defined in viewCreators.js and annoMatrix.js.
*/
import clip from "../util/clip";
import AnnoMatrix from "./annoMatrix";
import { _whereCacheCreate } from "./whereCache";
import { _isContinuousType, _getColumnSchema } from "./schema";
class AnnoMatrixView extends AnnoMatrix {
constructor(viewOf, rowIndex = null) {
const nObs = rowIndex ? rowIndex.size() : viewOf.nObs;
super(viewOf.schema, nObs, viewOf.nVar, rowIndex || viewOf.rowIndex);
this.viewOf = viewOf;
this.isView = true;
}
addObsAnnoCategory(col, category) {
const newAnnoMatrix = this._clone();
newAnnoMatrix.viewOf = this.viewOf.addObsAnnoCategory(col, category);
newAnnoMatrix.schema = newAnnoMatrix.viewOf.schema;
return newAnnoMatrix;
}
async removeObsAnnoCategory(col, category, unassignedCategory) {
const newAnnoMatrix = this._clone();
newAnnoMatrix.viewOf = await this.viewOf.removeObsAnnoCategory(
col,
category,
unassignedCategory
);
newAnnoMatrix.schema = newAnnoMatrix.viewOf.schema;
return newAnnoMatrix;
}
dropObsColumn(col) {
const newAnnoMatrix = this._clone();
newAnnoMatrix.viewOf = this.viewOf.dropObsColumn(col);
newAnnoMatrix._cache.obs = this._cache.obs.dropCol(col);
newAnnoMatrix.schema = newAnnoMatrix.viewOf.schema;
return newAnnoMatrix;
}
addObsColumn(colSchema, Ctor, value) {
const newAnnoMatrix = this._clone();
newAnnoMatrix.viewOf = this.viewOf.addObsColumn(colSchema, Ctor, value);
newAnnoMatrix.schema = newAnnoMatrix.viewOf.schema;
return newAnnoMatrix;
}
renameObsColumn(oldCol, newCol) {
const newAnnoMatrix = this._clone();
newAnnoMatrix.viewOf = this.viewOf.renameObsColumn(oldCol, newCol);
newAnnoMatrix.schema = newAnnoMatrix.viewOf.schema;
return newAnnoMatrix;
}
async setObsColumnValues(col, rowLabels, value) {
const newAnnoMatrix = this._clone();
newAnnoMatrix.viewOf = await this.viewOf.setObsColumnValues(
col,
rowLabels,
value
);
newAnnoMatrix._cache.obs = this._cache.obs.dropCol(col);
newAnnoMatrix.schema = newAnnoMatrix.viewOf.schema;
return newAnnoMatrix;
}
async resetObsColumnValues(col, oldValue, newValue) {
const newAnnoMatrix = this._clone();
newAnnoMatrix.viewOf = await this.viewOf.resetObsColumnValues(
col,
oldValue,
newValue
);
newAnnoMatrix._cache.obs = this._cache.obs.dropCol(col);
newAnnoMatrix.schema = newAnnoMatrix.viewOf.schema;
return newAnnoMatrix;
}
addEmbedding(colSchema) {
const newAnnoMatrix = this._clone();
newAnnoMatrix.viewOf = this.viewOf.addEmbedding(colSchema);
newAnnoMatrix.schema = newAnnoMatrix.viewOf.schema;
return newAnnoMatrix;
}
}
class AnnoMatrixMapView extends AnnoMatrixView {
/*
A view which knows how to transform its data.
*/
constructor(viewOf, mapFn) {
super(viewOf);
this.mapFn = mapFn;
}
async _doLoad(field, query) {
const df = await this.viewOf._fetch(field, query);
const dfMapped = df.mapColumns((colData, colIdx) => {
const colLabel = df.colIndex.getLabel(colIdx);
const colSchema = _getColumnSchema(this.schema, field, colLabel);
return this.mapFn(field, colLabel, colSchema, colData, df);
});
const whereCacheUpdate = _whereCacheCreate(
field,
query,
dfMapped.colIndex.labels()
);
return [whereCacheUpdate, dfMapped];
}
}
export class AnnoMatrixClipView extends AnnoMatrixMapView {
/*
A view which is a clipped transformation of its parent
*/
constructor(viewOf, qmin, qmax) {
super(viewOf, (field, colLabel, colSchema, colData, df) =>
_clipAnnoMatrix(field, colLabel, colSchema, colData, df, qmin, qmax)
);
this.isClipped = true;
this.clipRange = [qmin, qmax];
Object.seal(this);
}
}
export class AnnoMatrixRowSubsetView extends AnnoMatrixView {
/*
A view which is a subset of total rows.
*/
constructor(viewOf, rowIndex) {
super(viewOf, rowIndex);
Object.seal(this);
}
async _doLoad(field, query) {
const df = await this.viewOf._fetch(field, query);
// don't try to row-subset the var dimension.
if (field === "var") {
return [null, df];
}
const dfSubset = df.subset(null, null, this.rowIndex);
const whereCacheUpdate = _whereCacheCreate(
field,
query,
dfSubset.colIndex.labels()
);
return [whereCacheUpdate, dfSubset];
}
}
/*
Utility functions below
*/
function _clipAnnoMatrix(field, colLabel, colSchema, colData, df, qmin, qmax) {
/* only clip obs and var scalar columns */
if (field !== "obs" && field !== "X") return colData;
if (!_isContinuousType(colSchema)) return colData;
if (qmin < 0) qmin = 0;
if (qmax > 1) qmax = 1;
if (qmin === 0 && qmax === 1) return colData;
const quantiles = df.col(colLabel).summarize().percentiles;
const lower = quantiles[100 * qmin];
const upper = quantiles[100 * qmax];
const clippedData = clip(colData.slice(), lower, upper, Number.NaN);
return clippedData;
}
/* eslint-enable max-classes-per-file -- enable*/