Skip to content

Commit de588cb

Browse files
committed
Initial hooks for scfind + tests for URL hook param formatting
1 parent 65b64c4 commit de588cb

14 files changed

+482
-1
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
import { createScfindKey, annotationNamesToGetParams, SCFIND_BASE } from './utils';
2+
3+
describe('createScfindKey', () => {
4+
function expectURLIsValid(key: string) {
5+
expect(() => new URL(key)).not.toThrow();
6+
}
7+
8+
it('should use the appropriate scfind base URL', () => {
9+
const key = createScfindKey('endpoint', {});
10+
expect(key).toContain(SCFIND_BASE);
11+
expectURLIsValid(key);
12+
});
13+
14+
it.each(['endpoint1', 'endpoint2', 'endpoint3', 'my-weird-endpoint'])(
15+
'should use the appropriate provided endpoint',
16+
(endpoint) => {
17+
const key = createScfindKey(endpoint, {});
18+
expect(key).toContain(endpoint);
19+
expectURLIsValid(key);
20+
},
21+
);
22+
23+
it.each([
24+
{
25+
params: {
26+
param1: 'value1',
27+
param2: 'value2',
28+
param3: undefined,
29+
},
30+
definedKeys: ['param1', 'param2'],
31+
undefinedKeys: ['param3'],
32+
},
33+
])('should filter out undefined passed params', ({ params, definedKeys, undefinedKeys }) => {
34+
const key = createScfindKey('endpoint', params);
35+
definedKeys.forEach((k) => {
36+
expect(key.includes(k));
37+
});
38+
undefinedKeys.forEach((k) => {
39+
expect(!key.includes(k));
40+
});
41+
expectURLIsValid(key);
42+
});
43+
});
44+
45+
describe('annotationNamesToGetParams', () => {
46+
it('should return undefined if annotationNames is undefined', () => {
47+
expect(annotationNamesToGetParams(undefined)).toBeUndefined();
48+
});
49+
50+
it.each([
51+
{
52+
obj: [
53+
{ Organ: 'organ1', Tissue: 'tissue1' },
54+
{ Organ: 'organ1', Tissue: 'tissue2' },
55+
],
56+
expected: '[{"Organ": "organ1", "Tissue": "tissue1"},{"Organ": "organ1", "Tissue": "tissue2"}]',
57+
},
58+
])('should format annotation names correctly', ({ obj, expected }) => {
59+
expect(annotationNamesToGetParams(obj)).toBe(expected);
60+
});
61+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
interface AnnotationNames {
2+
Organ: string;
3+
Tissue: string;
4+
}
5+
6+
export type AnnotationNamesList = AnnotationNames[];
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
import useSWR from 'swr';
2+
import { fetcher } from 'js/helpers/swr';
3+
import { AnnotationNamesList } from './types';
4+
import { createScfindKey, annotationNamesToGetParams } from './utils';
5+
6+
interface CellTypeMarkerInfo {
7+
cellType: string;
8+
f1: number;
9+
fn: number;
10+
fp: number;
11+
genes: string;
12+
precision: number;
13+
recall: number;
14+
tp: number;
15+
}
16+
17+
interface CellTypeMarkersParams {
18+
cellTypes: string | string[];
19+
annotationNames: AnnotationNamesList;
20+
backgroundCellTypes?: string[];
21+
backgroundAnnotationNames?: AnnotationNamesList;
22+
topK?: number;
23+
sortField?: keyof CellTypeMarkerInfo;
24+
includePrefix?: boolean;
25+
}
26+
27+
type CellTypeMarkersKey = string;
28+
29+
interface CellTypeMarkersResponse {
30+
cellTypeMarkers: CellTypeMarkerInfo[];
31+
}
32+
33+
export function createCellTypeMarkersKey({
34+
cellTypes,
35+
annotationNames,
36+
backgroundCellTypes,
37+
backgroundAnnotationNames,
38+
topK,
39+
sortField,
40+
includePrefix,
41+
}: CellTypeMarkersParams): CellTypeMarkersKey {
42+
return createScfindKey('cellTypeMarkers', {
43+
cell_types: Array.isArray(cellTypes) ? cellTypes.join(',') : cellTypes,
44+
annotation_names: annotationNames ? annotationNamesToGetParams(annotationNames) : undefined,
45+
background_cell_types: Array.isArray(backgroundCellTypes) ? backgroundCellTypes.join(',') : backgroundCellTypes,
46+
background_annotation_names: annotationNamesToGetParams(backgroundAnnotationNames),
47+
top_k: topK ? topK.toString() : undefined,
48+
include_prefix: includePrefix ? String(includePrefix) : undefined,
49+
sort_field: sortField,
50+
});
51+
}
52+
53+
export default function useCellTypeMarkers({
54+
topK = 10,
55+
sortField = 'f1',
56+
includePrefix = true,
57+
...params
58+
}: CellTypeMarkersParams) {
59+
const key = createCellTypeMarkersKey({ topK, sortField, includePrefix, ...params });
60+
return useSWR<CellTypeMarkersResponse, unknown, CellTypeMarkersKey>(key, (url) => fetcher({ url }));
61+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import useSWR from 'swr';
2+
import { fetcher } from 'js/helpers/swr';
3+
import { createScfindKey, annotationNamesToGetParams } from './utils';
4+
import { AnnotationNamesList } from './types';
5+
6+
type CellTypeNamesKey = string;
7+
8+
interface CellTypeNamesParams {
9+
annotationNames: AnnotationNamesList;
10+
}
11+
12+
interface CellTypeNamesResponse {
13+
cellTypeNames: string[];
14+
}
15+
16+
export function createCellTypeNamesKey(annotationNames?: AnnotationNamesList): CellTypeNamesKey {
17+
return createScfindKey('cellTypeNames', {
18+
annotation_names: annotationNames ? annotationNamesToGetParams(annotationNames) : undefined,
19+
});
20+
}
21+
22+
export default function useCellTypeNames({ annotationNames }: CellTypeNamesParams) {
23+
const key = createCellTypeNamesKey(annotationNames);
24+
return useSWR<CellTypeNamesResponse, unknown, CellTypeNamesKey>(key, (url) => fetcher({ url }));
25+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import useSWR from 'swr';
2+
import { fetcher } from 'js/helpers/swr';
3+
import { createScfindKey, annotationNamesToGetParams } from './utils';
4+
import { AnnotationNamesList } from './types';
5+
6+
interface EvaluateMarkersParams {
7+
geneList: string | string[];
8+
cellTypes: string | string[];
9+
annotationNames?: AnnotationNamesList;
10+
backgroundCellTypes?: string[];
11+
backgroundAnnotationNames?: AnnotationNamesList;
12+
sortField?: string;
13+
includePrefix?: boolean;
14+
}
15+
16+
type EvaluateMarkersKey = string;
17+
18+
interface EvaluateMarkersResponse {
19+
evaluateMarkers: unknown;
20+
}
21+
22+
export function createCellTypeMarkersKey({
23+
geneList,
24+
cellTypes,
25+
annotationNames,
26+
backgroundCellTypes,
27+
backgroundAnnotationNames,
28+
sortField,
29+
includePrefix,
30+
}: EvaluateMarkersParams): EvaluateMarkersKey {
31+
return createScfindKey('evaluateMarkers', {
32+
gene_list: Array.isArray(geneList) ? geneList.join(',') : geneList,
33+
cell_types: Array.isArray(cellTypes) ? cellTypes.join(',') : cellTypes,
34+
annotation_names: annotationNamesToGetParams(annotationNames),
35+
background_cell_types: Array.isArray(backgroundCellTypes) ? backgroundCellTypes.join(',') : backgroundCellTypes,
36+
background_annotation_names: annotationNamesToGetParams(backgroundAnnotationNames),
37+
sort_field: sortField,
38+
include_prefix: includePrefix !== undefined ? String(includePrefix) : undefined,
39+
});
40+
}
41+
42+
export default function useEvaluateMarkers(params: EvaluateMarkersParams) {
43+
const key = createCellTypeMarkersKey(params);
44+
return useSWR<EvaluateMarkersResponse, unknown, EvaluateMarkersKey>(key, (url) => fetcher({ url }));
45+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import useSWR from 'swr';
2+
import { fetcher } from 'js/helpers/swr';
3+
import { createScfindKey, annotationNamesToGetParams } from './utils';
4+
import { AnnotationNamesList } from './types';
5+
6+
interface EvaluateMarkersParams {
7+
geneList?: string | string[];
8+
annotationNames?: AnnotationNamesList;
9+
minCells?: number;
10+
minFraction?: number;
11+
}
12+
13+
type EvaluateMarkersKey = string;
14+
15+
interface EvaluateMarkersResponse {
16+
evaluateMarkers: unknown;
17+
}
18+
19+
export function createCellTypeSpecificitiesKey({
20+
geneList,
21+
annotationNames,
22+
minCells,
23+
minFraction,
24+
}: EvaluateMarkersParams): EvaluateMarkersKey {
25+
return createScfindKey('findCellTypeSpecificities', {
26+
annotation_names: annotationNamesToGetParams(annotationNames),
27+
gene_list: Array.isArray(geneList) ? geneList.join(',') : geneList,
28+
min_cells: minCells ? String(minCells) : undefined,
29+
min_fraction: minFraction ? String(minFraction) : undefined,
30+
});
31+
}
32+
33+
export default function useFindCellTypeSpecificities(params: EvaluateMarkersParams) {
34+
const key = createCellTypeSpecificitiesKey(params);
35+
return useSWR<EvaluateMarkersResponse, unknown, EvaluateMarkersKey>(key, (url) => fetcher({ url }));
36+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import useSWR from 'swr';
2+
import { fetcher } from 'js/helpers/swr';
3+
import { createScfindKey, annotationNamesToGetParams } from './utils';
4+
import { AnnotationNamesList } from './types';
5+
6+
interface FindGeneSignaturesParams {
7+
cellTypes?: string | string[];
8+
annotationNames?: AnnotationNamesList;
9+
minCells?: number;
10+
minFraction?: number;
11+
}
12+
13+
type FindGeneSignaturesKey = string;
14+
15+
interface FindGeneSignaturesResponse {
16+
evaluateMarkers: unknown;
17+
}
18+
19+
export function createFindGeneSignaturesKey({
20+
cellTypes,
21+
annotationNames,
22+
minCells,
23+
minFraction,
24+
}: FindGeneSignaturesParams): FindGeneSignaturesKey {
25+
return createScfindKey('findGeneSignatures', {
26+
cell_types: Array.isArray(cellTypes) ? cellTypes.join(',') : cellTypes,
27+
annotation_names: annotationNamesToGetParams(annotationNames),
28+
min_cells: minCells ? String(minCells) : undefined,
29+
min_fraction: minFraction ? String(minFraction) : undefined,
30+
});
31+
}
32+
33+
export default function useFindGeneSignatures(params: FindGeneSignaturesParams) {
34+
const key = createFindGeneSignaturesKey(params);
35+
return useSWR<FindGeneSignaturesResponse, unknown, FindGeneSignaturesKey>(key, (url) => fetcher({ url }));
36+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import useSWR from 'swr';
2+
import { fetcher } from 'js/helpers/swr';
3+
import { createScfindKey, annotationNamesToGetParams } from './utils';
4+
import { AnnotationNamesList } from './types';
5+
6+
interface FindHouseKeepingGenesParams {
7+
cellTypes?: string | string[];
8+
annotationNames?: AnnotationNamesList;
9+
minRecall?: number;
10+
maxGenes?: number;
11+
}
12+
13+
type FindHouseKeepingGenesKey = string;
14+
15+
interface FindHouseKeepingGenesResponse {
16+
findHouseKeepingGenes: unknown;
17+
}
18+
19+
export function createFindHouseKeepingGenesKey({
20+
cellTypes,
21+
annotationNames,
22+
minRecall,
23+
maxGenes,
24+
}: FindHouseKeepingGenesParams): FindHouseKeepingGenesKey {
25+
return createScfindKey('findHouseKeepingGenes', {
26+
cell_types: Array.isArray(cellTypes) ? cellTypes.join(',') : cellTypes,
27+
annotation_names: annotationNamesToGetParams(annotationNames),
28+
min_recall: minRecall ? String(minRecall) : undefined,
29+
max_genes: maxGenes ? String(maxGenes) : undefined,
30+
});
31+
}
32+
33+
export default function useFindHouseKeepingGenes(params: FindHouseKeepingGenesParams) {
34+
const key = createFindHouseKeepingGenesKey(params);
35+
return useSWR<FindHouseKeepingGenesResponse, unknown, FindHouseKeepingGenesKey>(key, (url) => fetcher({ url }));
36+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import useSWR from 'swr';
2+
import { fetcher } from 'js/helpers/swr';
3+
import { createScfindKey, annotationNamesToGetParams } from './utils';
4+
import { AnnotationNamesList } from './types';
5+
6+
interface FindSimilarGenesParams {
7+
cellTypes?: string | string[];
8+
annotationNames?: AnnotationNamesList;
9+
minRecall?: number;
10+
maxGenes?: number;
11+
}
12+
13+
type FindSimilarGenesKey = string;
14+
15+
interface FindSimilarGenesResponse {
16+
evaluateMarkers: unknown;
17+
}
18+
19+
export function createFindSimilarGenesKey({
20+
cellTypes,
21+
annotationNames,
22+
minRecall,
23+
maxGenes,
24+
}: FindSimilarGenesParams): FindSimilarGenesKey {
25+
return createScfindKey('findSimilarGenes', {
26+
cell_types: Array.isArray(cellTypes) ? cellTypes.join(',') : cellTypes,
27+
annotation_names: annotationNamesToGetParams(annotationNames),
28+
min_recall: minRecall ? String(minRecall) : undefined,
29+
max_genes: maxGenes ? String(maxGenes) : undefined,
30+
});
31+
}
32+
33+
export default function useFindSimilarGenes(params: FindSimilarGenesParams) {
34+
const key = createFindSimilarGenesKey(params);
35+
return useSWR<FindSimilarGenesResponse, unknown, FindSimilarGenesKey>(key, (url) => fetcher({ url }));
36+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import useSWR from 'swr';
2+
import { fetcher } from 'js/helpers/swr';
3+
import { createScfindKey } from './utils';
4+
5+
interface FindTissueSpecificitiesParams {
6+
geneList?: string | string[];
7+
minCells?: number;
8+
}
9+
10+
type FindTissueSpecificitiesKey = string;
11+
12+
interface FindTissueSpecificitiesResponse {
13+
evaluateMarkers: unknown;
14+
}
15+
16+
export function FindTissueSpecificitiesKey({
17+
geneList,
18+
minCells,
19+
}: FindTissueSpecificitiesParams): FindTissueSpecificitiesKey {
20+
return createScfindKey('findTissueSpecificities', {
21+
gene_list: Array.isArray(geneList) ? geneList.join(',') : geneList,
22+
min_cells: minCells ? String(minCells) : undefined,
23+
});
24+
}
25+
26+
export default function useFindTissueSpecificities(params: FindTissueSpecificitiesParams) {
27+
const key = FindTissueSpecificitiesKey(params);
28+
return useSWR<FindTissueSpecificitiesResponse, unknown, FindTissueSpecificitiesKey>(key, (url) => fetcher({ url }));
29+
}

0 commit comments

Comments
 (0)