Skip to content

Commit

Permalink
Merge pull request #1331 from nextstrain/feat/better-suggestions-sort
Browse files Browse the repository at this point in the history
  • Loading branch information
ivan-aksamentov authored Dec 8, 2023
2 parents d3e8b47 + e2d713c commit c72f417
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 15 deletions.
36 changes: 33 additions & 3 deletions packages_rs/nextclade-web/src/hooks/useRunSeqAutodetect.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { first, get, isNil, sortBy } from 'lodash'
import { first, get, isNil, mean, sortBy, uniq } from 'lodash'
import type { Subscription } from 'observable-fns'
import { useMemo } from 'react'
import { useRecoilCallback, useRecoilValue } from 'recoil'
Expand All @@ -9,7 +9,6 @@ import {
autodetectResultsAtom,
AutodetectRunState,
autodetectRunStateAtom,
groupByDatasets,
minimizerIndexAtom,
} from 'src/state/autodetect.state'
import { datasetsAtom, minimizerIndexVersionAtom } from 'src/state/dataset.state'
Expand Down Expand Up @@ -114,6 +113,32 @@ export class SeqAutodetectWasmWorker {
}
}

export function groupByDatasets(records: MinimizerSearchRecord[]) {
const names = uniq(records.flatMap((record) => record.result.datasets.map((dataset) => dataset.name)))
let byDataset: Record<string, { records: MinimizerSearchRecord[]; meanScore: number }> = {}
// eslint-disable-next-line no-loops/no-loops
for (const name of names) {
// Find sequence records which match this dataset
const selectedRecords = records.filter((record) => record.result.datasets.some((dataset) => dataset.name === name))

// Get scores for sequence records which match this dataset
const scores = selectedRecords.map((record) => {
const dataset = record.result.datasets.find((ds) => ds.name === name)
return dataset?.score ?? 0
})
const meanScore = mean(scores)

byDataset = { ...byDataset, [name]: { records: selectedRecords, meanScore } }
}

console.info(
sortBy(Object.entries(byDataset), ([_, val]) => -val.meanScore)
.map(([name, val]) => `${name.padEnd(60)} ${val.meanScore.toFixed(4)}`)
.join('\n'),
)
return byDataset
}

export function useDatasetSuggestionResults() {
const { datasets } = useRecoilValue(datasetsAtom)
const autodetectResults = useRecoilValue(autodetectResultsAtom)
Expand All @@ -128,7 +153,12 @@ export function useDatasetSuggestionResults() {
Object.entries(recordsByDataset).some(([dataset, _]) => dataset === candidate.path),
)

itemsInclude = sortBy(itemsInclude, (dataset) => -get(recordsByDataset, dataset.path, []).length)
itemsInclude = sortBy(itemsInclude, (dataset) => {
const record = get(recordsByDataset, dataset.path)
return -record.meanScore
})

itemsInclude = sortBy(itemsInclude, (dataset) => -(get(recordsByDataset, dataset.path)?.records?.length ?? 0))

const itemsNotInclude = datasets.filter((candidate) => !itemsInclude.map((it) => it.path).includes(candidate.path))

Expand Down
13 changes: 1 addition & 12 deletions packages_rs/nextclade-web/src/state/autodetect.state.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
/* eslint-disable no-loops/no-loops */
import { isEmpty, isNil, uniq } from 'lodash'
import { isEmpty, isNil } from 'lodash'
import { atom, atomFamily, DefaultValue, selector, selectorFamily } from 'recoil'
import { isDefaultValue } from 'src/state/utils/isDefaultValue'
import type { MinimizerIndexJson, MinimizerSearchRecord } from 'src/types'
Expand Down Expand Up @@ -49,16 +48,6 @@ export const autodetectResultByIndexAtom = selectorFamily<MinimizerSearchRecord,
// Dataset ID to use for when dataset is not autodetected
export const DATASET_ID_UNDETECTED = 'undetected'

export function groupByDatasets(records: MinimizerSearchRecord[]): Record<string, MinimizerSearchRecord[]> {
const names = uniq(records.flatMap((record) => record.result.datasets.map((dataset) => dataset.name)))
let byDataset = {}
for (const name of names) {
const selectedRecords = records.filter((record) => record.result.datasets.some((dataset) => dataset.name === name))
byDataset = { ...byDataset, [name]: selectedRecords }
}
return byDataset
}

// Select autodetect results by dataset name
export const autodetectResultsByDatasetAtom = selectorFamily<MinimizerSearchRecord[] | undefined, string>({
key: 'autodetectResultByDatasetAtom',
Expand Down

1 comment on commit c72f417

@vercel
Copy link

@vercel vercel bot commented on c72f417 Dec 8, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

nextclade – ./

nextclade-nextstrain.vercel.app
nextclade-git-master-nextstrain.vercel.app
nextclade.vercel.app

Please sign in to comment.