Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Spatial Mode User Story 1 #805

Merged
merged 22 commits into from
Mar 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions client/__tests__/e2e/e2e.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/**

Check failure on line 1 in client/__tests__/e2e/e2e.test.ts

View workflow job for this annotation

GitHub Actions / smoke-tests

[chromium] › e2e/e2e.test.ts:690:9 › geneSET crud operations and interactions subset › edit geneset name and undo/redo

1) [chromium] › e2e/e2e.test.ts:690:9 › geneSET crud operations and interactions subset › edit geneset name and undo/redo Test timeout of 150000ms exceeded.
* Smoke test suite that will be run in GHA
* Tests included in this file are expected to be relatively stable and test core features
*
Expand Down Expand Up @@ -491,7 +491,7 @@
page,
true
);
expect(page.getByTestId("lasso-element")).toBeVisible();
await expect(page.getByTestId("lasso-element")).toBeVisible();

const initialCount = await getCellSetCount(1, page);

Expand Down Expand Up @@ -525,7 +525,7 @@
true
);

expect(page.getByTestId("lasso-element")).toBeVisible();
await expect(page.getByTestId("lasso-element")).toBeVisible();

const initialCount = await getCellSetCount(1, page);

Expand Down
17 changes: 8 additions & 9 deletions client/__tests__/e2e/playwright.global.setup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,15 +42,14 @@ const setup = async ({ page }: { page: Page }) => {
},
});
});

// page.on("console", (message) => {
// if (message.type() === "error") {
// throw new Error(`CLIENT SIDE ERROR: ${ message.text()}`);
// }
// });
// page.on("pageerror", (error) => {
// throw new Error(`UNCAUGHT CLIENT ERROR: ${ error}`);
// });
page.on("console", (message) => {
if (message.type() === "error") {
throw new Error(`CLIENT SIDE ERROR: ${JSON.stringify(message)}`);
}
});
page.on("pageerror", (error) => {
throw new Error(`UNCAUGHT CLIENT ERROR: ${error}`);
});
};

export default setup;
44 changes: 41 additions & 3 deletions client/src/actions/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,12 @@ import * as genesetActions from "./geneset";
import { AppDispatch, GetState } from "../reducers";
import { EmbeddingSchema, Field, Schema } from "../common/types/schema";
import { ConvertedUserColors } from "../reducers/colors";
import type { DatasetMetadata, Dataset, S3URI } from "../common/types/entities";
import type {
DatasetMetadata,
Dataset,
S3URI,
DatasetSpatialMetadata,
} from "../common/types/entities";
import { postExplainNewTab } from "../components/framework/toasters";
import { KEYS } from "../components/util/localStorage";
import {
Expand All @@ -29,7 +34,11 @@ import { packDiffExPdu, DiffExMode, DiffExArguments } from "../util/diffexpdu";
import { track } from "../analytics";
import { EVENTS } from "../analytics/events";
import AnnoMatrix from "../annoMatrix/annoMatrix";
import { checkFeatureFlags } from "../util/featureFlags/featureFlags";
import {
checkFeatureFlags,
getFeatureFlag,
} from "../util/featureFlags/featureFlags";
import { FEATURES } from "../util/featureFlags/features";
import { DATASET_METADATA_RESPONSE } from "../../__tests__/__mocks__/apiMock";

function setGlobalConfig(config: Config) {
Expand Down Expand Up @@ -126,6 +135,31 @@ async function datasetMetadataFetchAndLoad(
});
}

/**
* Fetches and loads dataset spatial metadata.
* @param dispatch - Function facilitating update of store.
* @param oldPrefix - API prefix with dataset path that dataset metadata lives on. (Not S3 URI)
*/
async function datasetSpatialMetadataFetchAndLoad(
dispatch: AppDispatch,
oldPrefix: string
): Promise<void> {
try {
const datasetSpatialMetadataResponse = await fetchJson<{
metadata: DatasetSpatialMetadata;
}>("spatial/meta", oldPrefix);
dispatch({
type: "request spatial metadata success",
data: datasetSpatialMetadataResponse,
});
} catch (error) {
dispatch({
type: "request spatial metadata error",
error,
});
}
}

interface GeneInfoAPI {
ncbi_url: string;
name: string;
Expand Down Expand Up @@ -178,6 +212,7 @@ const doInitialDataLoad = (): ((

// check URL for feature flags
checkFeatureFlags();
const isSpatial = getFeatureFlag(FEATURES.SPATIAL);

try {
const s3URI = await s3URIFetch();
Expand All @@ -190,7 +225,10 @@ const doInitialDataLoad = (): ((
]);

datasetMetadataFetchAndLoad(dispatch, oldPrefix, config);

// TODO: add logic to ensure this is working for spatial datasets when flag removed
if (isSpatial) {
kaloster marked this conversation as resolved.
Show resolved Hide resolved
datasetSpatialMetadataFetchAndLoad(dispatch, oldPrefix);
}
const baseDataUrl = `${globals.API.prefix}${globals.API.version}`;
const annoMatrix = new AnnoMatrixLoader(baseDataUrl, schema.schema);
const obsCrossfilter = new AnnoMatrixObsCrossfilter(annoMatrix);
Expand Down
3 changes: 3 additions & 0 deletions client/src/common/types/entities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,9 @@ export interface DatasetMetadata {
s3_URI: S3URI;
}

// TODO: proper typing after migration and final CXG schema
export type DatasetSpatialMetadata = any;

export type S3URI = string;

/**
Expand Down
25 changes: 15 additions & 10 deletions client/src/components/embedding/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,11 @@ import { EVENTS } from "../../analytics/events";
type EmbeddingState = any;

// @ts-expect-error ts-migrate(1238) FIXME: Unable to resolve signature of class decorator whe... Remove this comment to see the full error message
@connect((state) => ({
// eslint-disable-next-line @typescript-eslint/no-explicit-any --- FIXME: disabled temporarily on migrate to TS.
layoutChoice: (state as any).layoutChoice,
// eslint-disable-next-line @typescript-eslint/no-explicit-any --- FIXME: disabled temporarily on migrate to TS.
schema: (state as any).annoMatrix?.schema,
// eslint-disable-next-line @typescript-eslint/no-explicit-any --- FIXME: disabled temporarily on migrate to TS.
crossfilter: (state as any).obsCrossfilter,
@connect((state: RootState) => ({
layoutChoice: state.layoutChoice,
schema: state.annoMatrix?.schema,
crossfilter: state.obsCrossfilter,
imageUnderlay: state.imageUnderlay,
}))
// eslint-disable-next-line @typescript-eslint/ban-types --- FIXME: disabled temporarily on migrate to TS.
class Embedding extends React.PureComponent<{}, EmbeddingState> {
Expand All @@ -41,14 +39,21 @@ class Embedding extends React.PureComponent<{}, EmbeddingState> {
track(EVENTS.EXPLORER_LAYOUT_CHOICE_BUTTON_CLICKED);
};

// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any -- - FIXME: disabled temporarily on migrate to TS.
handleLayoutChoiceChange = (e: any) => {
handleLayoutChoiceChange = (e: React.ChangeEvent<HTMLInputElement>) => {
// @ts-expect-error ts-migrate(2339) FIXME: Property 'dispatch' does not exist on type 'Readon... Remove this comment to see the full error message
const { dispatch } = this.props;
const { dispatch, imageUnderlay } = this.props;

track(EVENTS.EXPLORER_LAYOUT_CHOICE_CHANGE_ITEM_CLICKED);

dispatch(actions.layoutChoiceAction(e.currentTarget.value));
if (
imageUnderlay.isActive &&
e.target.value !== globals.spatialEmbeddingKeyword
) {
dispatch({
type: "toggle image underlay",
});
}
};

// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types --- FIXME: disabled temporarily on migrate to TS.
Expand Down
66 changes: 66 additions & 0 deletions client/src/components/graph/drawSpatialImageRegl.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import { Regl, Texture2D } from "regl";

interface ReglProps {
rectCoords: Float32Array;
spatialImageAsTexture: Texture2D;
projView: number[];
imageWidth: number;
imageHeight: number;
count: number;
}

export default function drawSpatialImageRegl(regl: Regl) {
return regl({
frag: `
precision mediump float;
// our texture
uniform sampler2D u_image;
// the texCoords passed in from the vertex shader.
varying vec2 v_texCoord;
void main() {
gl_FragColor = texture2D(u_image, v_texCoord);
}`,

vert: `
attribute vec2 a_position;
attribute vec2 a_texCoord;
uniform vec2 u_resolution;
uniform mat3 projView;
varying vec2 v_texCoord;
void main() {
// convert the rectangle from pixels to 0.0 to 1.0
vec3 pos = vec3(a_position, 1.);
vec2 zeroToOne = pos.xy / u_resolution;
// convert from 0->1 to 0->2
vec2 zeroToTwo = zeroToOne * 2.0;
// convert from 0->2 to -1->+1 (clipspace)
vec2 clipSpace = zeroToTwo - 1.0;
vec3 pos2 = projView * vec3(clipSpace, 1.);
gl_Position = vec4(pos2.xy , 0, 1);
// pass the texCoord to the fragment shader
// The GPU will interpolate this value between points.
v_texCoord = a_texCoord;
}`,

attributes: {
a_texCoord: [0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 1.0, 1.0, 0.0, 1.0, 1.0],
a_position: regl.prop<ReglProps, "rectCoords">("rectCoords"),
},

uniforms: {
projView: regl.prop<ReglProps, "projView">("projView"),
u_image: regl.prop<ReglProps, "spatialImageAsTexture">(
"spatialImageAsTexture"
),
color: [1, 0, 0, 1],
u_resolution: [
regl.prop<ReglProps, "imageWidth">("imageWidth"),
regl.prop<ReglProps, "imageHeight">("imageHeight"),
],
image_width: regl.prop<ReglProps, "imageWidth">("imageWidth"),
},
// This tells regl the number of vertices to draw in this command
// https://github.com/regl-project/regl
count: 6,
kaloster marked this conversation as resolved.
Show resolved Hide resolved
});
}
Loading
Loading