mirror of
https://github.com/chanzuckerberg/cellxgene.git
synced 2026-09-19 02:48:30 +08:00
* 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>
177 lines
5.1 KiB
JavaScript
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*/
|