Skip to content

Commit

Permalink
feat(components): add insertion tab for mutations component
Browse files Browse the repository at this point in the history
  • Loading branch information
JonasKellerer committed Apr 8, 2024
1 parent 0797bf4 commit 7259feb
Show file tree
Hide file tree
Showing 38 changed files with 845 additions and 488 deletions.
34 changes: 34 additions & 0 deletions components/src/operator/FetchInsertionsOperator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { type Dataset } from './Dataset';
import { type Operator } from './Operator';
import { type InsertionEntry, type LapisFilter, type SequenceType } from '../types';
import { MutationCache } from '../utils/mutations';
import { mapLapisFilterToUrlParams } from '../utils/utils';

export class FetchInsertionsOperator implements Operator<InsertionEntry> {
constructor(
private filter: LapisFilter,
private sequenceType: SequenceType,
) {}

private async fetchInsertions(
lapis: string,
signal?: AbortSignal,
): Promise<{ insertion: string; count: number }[]> {
const endpoint = `${this.sequenceType === 'nucleotide' ? 'nuc' : 'aa'}-insertions`;
const params = mapLapisFilterToUrlParams(this.filter);
return (await (await fetch(`${lapis}/${endpoint}?${params.toString()}`, { signal })).json()).data;
}

async evaluate(lapis: string, signal?: AbortSignal): Promise<Dataset<InsertionEntry>> {
const [insertions] = await Promise.all([this.fetchInsertions(lapis, signal)]);

const mutationCache = MutationCache.getInstance();
const content: InsertionEntry[] = insertions.map(({ insertion, count }) => ({
type: 'insertion',
mutation: mutationCache.getInsertion(insertion),
count,
}));

return { content };
}
}
77 changes: 0 additions & 77 deletions components/src/operator/FetchMutationsOperator.ts

This file was deleted.

39 changes: 39 additions & 0 deletions components/src/operator/FetchSubstitutionsOrDeletionsOperator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { type Dataset } from './Dataset';
import { type Operator } from './Operator';
import { type LapisFilter, type SequenceType, type SubstitutionOrDeletionEntry } from '../types';
import { MutationCache, Substitution } from '../utils/mutations';
import { mapLapisFilterToUrlParams } from '../utils/utils';

export class FetchSubstitutionsOrDeletionsOperator implements Operator<SubstitutionOrDeletionEntry> {
constructor(
private filter: LapisFilter,
private sequenceType: SequenceType,
private minProportion?: number,
) {}

async evaluate(lapis: string, signal?: AbortSignal): Promise<Dataset<SubstitutionOrDeletionEntry>> {
const [mutations] = await Promise.all([this.fetchMutations(lapis, signal)]);

const instance = MutationCache.getInstance();
const content: SubstitutionOrDeletionEntry[] = mutations.map(({ mutation, count, proportion }) => {
const parsed = instance.getSubstitutionOrDeletion(mutation);
return parsed instanceof Substitution
? { type: 'substitution', mutation: parsed, count, proportion }
: { type: 'deletion', mutation: parsed, count, proportion };
});

return { content };
}

private async fetchMutations(
lapis: string,
signal?: AbortSignal,
): Promise<{ mutation: string; count: number; proportion: number }[]> {
const endpoint = `${this.sequenceType === 'nucleotide' ? 'nuc' : 'aa'}-mutations`;
const params = mapLapisFilterToUrlParams(this.filter);
if (this.minProportion !== undefined) {
params.set('minProportion', this.minProportion.toString());
}
return (await (await fetch(`${lapis}/${endpoint}?${params.toString()}`, { signal })).json()).data;
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { describe, expect, it } from 'vitest';

import { filterMutationData } from './queryMutationData';
import { type MutationEntry, type SubstitutionOrDeletion } from '../../operator/FetchMutationsOperator';
import { type SubstitutionOrDeletion, type SubstitutionOrDeletionEntry } from '../../types';
import { Deletion, Substitution } from '../../utils/mutations';

const segment = 'testSegment';
Expand All @@ -14,7 +14,7 @@ describe('filterMutationData', () => {
}: {
segment: string | undefined;
type: SubstitutionOrDeletion;
}): MutationEntry {
}): SubstitutionOrDeletionEntry {
switch (type) {
case 'substitution':
return {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,6 @@ export function getMutationComparisonTableData(data: Dataset<MutationData>) {

for (const mutationData of data.content) {
for (const mutationEntry of mutationData.data) {
if (mutationEntry.type === 'insertion') {
continue;
}
const mutation = mutationEntry.mutation.toString();
const proportions = mutationsToProportions.get(mutation) || {};
proportions[mutationData.displayName] = mutationEntry.proportion;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export const MutationComparisonVenn: FunctionComponent<MutationComparisonVennPro
.map((mutationData) => {
return {
...mutationData,
data: mutationData.data.filter((mutationEntry) => mutationEntry.type !== 'insertion'),
data: mutationData.data,
};
})
.map((mutationData) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@ import { getMutationComparisonTableData } from './getMutationComparisonTableData
import { MutationComparisonTable } from './mutation-comparison-table';
import { MutationComparisonVenn } from './mutation-comparison-venn';
import { filterMutationData, type MutationData, queryMutationData } from './queryMutationData';
import { type SubstitutionOrDeletion } from '../../operator/FetchMutationsOperator';
import { type LapisFilter, type SequenceType } from '../../types';
import { type LapisFilter, type SequenceType, type SubstitutionOrDeletion } from '../../types';
import { LapisUrlContext } from '../LapisUrlContext';
import { type DisplayedSegment, SegmentSelector } from '../components/SegmentSelector';
import { type CheckboxItem, CheckboxSelector } from '../components/checkbox-selector';
Expand Down
12 changes: 6 additions & 6 deletions components/src/preact/mutationComparison/queryMutationData.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { type DisplayedMutationType, type MutationComparisonVariant } from './mutation-comparison';
import { type MutationEntry } from '../../operator/FetchMutationsOperator';
import { queryMutations } from '../../query/queryMutations';
import { querySubstitutionsOrDeletions } from '../../query/querySubstitutionsOrDeletions';
import { type SubstitutionOrDeletionEntry } from '../../types';
import { type DisplayedSegment } from '../components/SegmentSelector';

export type MutationData = {
displayName: string;
data: MutationEntry[];
data: SubstitutionOrDeletionEntry[];
};

export async function queryMutationData(
Expand All @@ -17,7 +17,7 @@ export async function queryMutationData(
variants.map(async (variant) => {
return {
displayName: variant.displayName,
data: (await queryMutations(variant.lapisFilter, sequenceType, lapis)).content,
data: (await querySubstitutionsOrDeletions(variant.lapisFilter, sequenceType, lapis)).content,
};
}),
);
Expand All @@ -35,7 +35,7 @@ export function filterMutationData(
displayedSegments: DisplayedSegment[],
displayedMutationTypes: DisplayedMutationType[],
) {
const byDisplayedSegments = (mutationEntry: MutationEntry) => {
const byDisplayedSegments = (mutationEntry: SubstitutionOrDeletionEntry) => {
if (mutationEntry.mutation.segment === undefined) {
return true;
}
Expand All @@ -44,7 +44,7 @@ export function filterMutationData(
displayedSegment.segment === mutationEntry.mutation.segment && displayedSegment.checked,
);
};
const byDisplayedMutationTypes = (mutationEntry: MutationEntry) => {
const byDisplayedMutationTypes = (mutationEntry: SubstitutionOrDeletionEntry) => {
return displayedMutationTypes.some(
(displayedMutationType) =>
displayedMutationType.checked && displayedMutationType.type === mutationEntry.type,
Expand Down
36 changes: 36 additions & 0 deletions components/src/preact/mutations/getInsertionsTableData.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { describe, expect, test } from 'vitest';

import { getInsertionsTableData } from './getInsertionsTableData';
import { Insertion } from '../../utils/mutations';

describe('getInsertionsTableData', () => {
test('should return the correct data', () => {
const data = [
{
type: 'insertion' as const,
mutation: new Insertion('segment1', 123, 'T'),
count: 1,
proportion: 0.1,
},
{
type: 'insertion' as const,
mutation: new Insertion('segment2', 234, 'AAA'),
count: 2,
proportion: 0.2,
},
];

const result = getInsertionsTableData(data);

expect(result).toEqual([
{
insertion: 'ins_segment1:123:T',
count: 1,
},
{
insertion: 'ins_segment2:234:AAA',
count: 2,
},
]);
});
});
10 changes: 10 additions & 0 deletions components/src/preact/mutations/getInsertionsTableData.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { type InsertionEntry } from '../../types';

export function getInsertionsTableData(data: InsertionEntry[]) {
return data.map((mutationEntry) => {
return {
insertion: mutationEntry.mutation.toString(),
count: mutationEntry.count,
};
});
}
40 changes: 40 additions & 0 deletions components/src/preact/mutations/getMutationsTableData.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { describe, expect, test } from 'vitest';

import { getMutationsTableData } from './getMutationsTableData';
import { Deletion, Substitution } from '../../utils/mutations';

describe('getMutationsTableData', () => {
test('should return the correct data', () => {
const data = [
{
type: 'substitution' as const,
mutation: new Substitution('segment1', 'A', 'T', 123),
count: 1,
proportion: 0.1,
},
{
type: 'deletion' as const,
mutation: new Deletion('segment2', 'C', 123),
count: 2,
proportion: 0.2,
},
];

const result = getMutationsTableData(data);

expect(result).toEqual([
{
mutation: 'segment1:A123T',
type: 'substitution',
count: 1,
proportion: 0.1,
},
{
mutation: 'segment2:C123-',
type: 'deletion',
count: 2,
proportion: 0.2,
},
]);
});
});
12 changes: 12 additions & 0 deletions components/src/preact/mutations/getMutationsTableData.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { type SubstitutionOrDeletionEntry } from '../../types';

export function getMutationsTableData(data: SubstitutionOrDeletionEntry[]) {
return data.map((mutationEntry) => {
return {
mutation: mutationEntry.mutation.toString(),
type: mutationEntry.type,
count: mutationEntry.count,
proportion: mutationEntry.proportion,
};
});
}

0 comments on commit 7259feb

Please sign in to comment.