Skip to content

Commit

Permalink
Merge pull request #1440 from nextstrain/feat/web-select-dataset-when…
Browse files Browse the repository at this point in the history
…-trigger-manual
  • Loading branch information
ivan-aksamentov authored Apr 23, 2024
2 parents aaceed8 + cf11c75 commit b3c410d
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 36 deletions.
6 changes: 4 additions & 2 deletions packages/nextclade-web/src/components/Main/MainInputForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import styled from 'styled-components'
import { SuggestionAlertMainPage } from 'src/components/Main/SuggestionAlertMainPage'
import { datasetCurrentAtom } from 'src/state/dataset.state'
import { useQuerySeqInputs } from 'src/state/inputs.state'
import { autodetectShouldSetCurrentDatasetAtom } from 'src/state/autodetect.state'
import { useDatasetSuggestionResults } from 'src/hooks/useRunSeqAutodetect'
import { useUpdatedDatasetIndex } from 'src/io/fetchDatasets'
import { ButtonChangeDataset, DatasetNoneSection } from 'src/components/Main/ButtonChangeDataset'
Expand Down Expand Up @@ -158,12 +159,13 @@ function DatasetCurrentOrSelectButton() {
const run = useRunAnalysis()
const [dataset, setDataset] = useRecoilState(datasetCurrentAtom)
const { topSuggestion } = useDatasetSuggestionResults()
const autodetectShouldSetCurrentDataset = useRecoilValue(autodetectShouldSetCurrentDatasetAtom)

useEffect(() => {
if (!dataset) {
if (!dataset || autodetectShouldSetCurrentDataset) {
setDataset(topSuggestion)
}
}, [dataset, setDataset, topSuggestion])
}, [autodetectShouldSetCurrentDataset, dataset, setDataset, topSuggestion])

const { push } = useRouter()
const toDatasetSelection = useCallback(() => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ export function SuggestionPanel() {
export function ButtonSuggest() {
const { t } = useTranslationSafe()
const hasRequiredInputs = useRecoilValue(hasRequiredInputsAtom)
const runSuggest = useRunSeqAutodetect()
const runSuggest = useRunSeqAutodetect({ shouldSetCurrentDataset: true })
const hasAutodetectResults = useRecoilValue(hasAutodetectResultsAtom)
const autodetectRunState = useRecoilValue(autodetectRunStateAtom)

Expand Down
66 changes: 33 additions & 33 deletions packages/nextclade-web/src/hooks/useRunSeqAutodetect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,13 @@ import {
autodetectResultsAtom,
AutodetectRunState,
autodetectRunStateAtom,
autodetectShouldSetCurrentDatasetAtom,
minimizerIndexAtom,
} from 'src/state/autodetect.state'
import { datasetsAtom, minimizerIndexVersionAtom } from 'src/state/dataset.state'
import { globalErrorAtom } from 'src/state/error.state'
import { MinimizerIndexJson, MinimizerSearchRecord } from 'src/types'
import { qrySeqInputsStorageAtom } from 'src/state/inputs.state'
import type { Dataset, MinimizerIndexJson, MinimizerSearchRecord } from 'src/types'
import { getQueryFasta } from 'src/workers/launchAnalysis'
import { NextcladeSeqAutodetectWasmWorker } from 'src/workers/nextcladeAutodetect.worker'
import { spawn } from 'src/workers/spawn'
Expand All @@ -23,7 +24,7 @@ export interface AutosuggestionParams {
shouldSetCurrentDataset?: boolean
}

export function useRunSeqAutodetect() {
export function useRunSeqAutodetect(params?: AutosuggestionParams) {
return useRecoilCallback(
({ set, reset, snapshot }) =>
() => {
Expand All @@ -32,6 +33,7 @@ export function useRunSeqAutodetect() {
reset(minimizerIndexAtom)
reset(autodetectResultsAtom)
reset(autodetectRunStateAtom)
reset(autodetectShouldSetCurrentDatasetAtom)

function onResult(results: MinimizerSearchRecord[]) {
results.forEach((res) => {
Expand All @@ -46,6 +48,7 @@ export function useRunSeqAutodetect() {

function onComplete() {
set(autodetectRunStateAtom, AutodetectRunState.Done)
set(autodetectShouldSetCurrentDatasetAtom, params?.shouldSetCurrentDataset ?? false)
}

set(autodetectRunStateAtom, AutodetectRunState.Started)
Expand All @@ -64,7 +67,7 @@ export function useRunSeqAutodetect() {
throw error
})
},
[],
[params?.shouldSetCurrentDataset],
)
}

Expand Down Expand Up @@ -136,44 +139,41 @@ export function groupByDatasets(records: MinimizerSearchRecord[]) {
export function useDatasetSuggestionResults() {
const { datasets } = useRecoilValue(datasetsAtom)
const autodetectResults = useRecoilValue(autodetectResultsAtom)
const result = useMemo(() => {
if (isNil(autodetectResults) || autodetectResults.length === 0) {
return { itemsStartWith: [], itemsInclude: datasets, itemsNotInclude: [] }
}

const recordsByDataset = groupByDatasets(autodetectResults)

let itemsInclude = datasets.filter((candidate) =>
Object.entries(recordsByDataset).some(([dataset, _]) => dataset === candidate.path),
)

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

itemsInclude = sortBy(itemsInclude, (dataset) => -(get(recordsByDataset, dataset.path)?.records?.length ?? 0))
export function processSuggestionResults(datasets: Dataset[], autodetectResults: MinimizerSearchRecord[] | undefined) {
if (isNil(autodetectResults) || autodetectResults.length === 0) {
return {
datasetsActive: datasets,
datasetsInactive: [],
topSuggestion: undefined,
showSuggestions: false,
numSuggestions: datasets.length,
}
}

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

return { itemsStartWith: [], itemsInclude, itemsNotInclude }
}, [autodetectResults, datasets])
let itemsInclude = datasets.filter((candidate) =>
Object.entries(recordsByDataset).some(([dataset, _]) => dataset === candidate.path),
)

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

const datasetsInactive = useMemo(() => {
const { itemsNotInclude } = result
return itemsNotInclude
}, [result])
itemsInclude = sortBy(itemsInclude, (dataset) => -(get(recordsByDataset, dataset.path)?.records?.length ?? 0))

const showSuggestions = useMemo(() => !isNil(autodetectResults) && autodetectResults.length > 0, [autodetectResults])
const itemsNotInclude = datasets.filter((candidate) => !itemsInclude.map((it) => it.path).includes(candidate.path))

const topSuggestion = autodetectResults ? first(datasetsActive) : undefined
const showSuggestions = !isNil(autodetectResults) && autodetectResults.length > 0

const numSuggestions = autodetectResults ? datasetsActive.length : 0
const datasetsActive = itemsInclude
const datasetsInactive = itemsNotInclude
const topSuggestion = first(datasetsActive)
const numSuggestions = datasetsActive.length

return { datasetsActive, datasetsInactive, topSuggestion, showSuggestions, numSuggestions }
}
5 changes: 5 additions & 0 deletions packages/nextclade-web/src/state/autodetect.state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -126,3 +126,8 @@ export const isAutodetectRunningAtom = selector({
key: 'isAutodetectRunningAtom',
get: ({ get }) => get(autodetectRunStateAtom) === AutodetectRunState.Started,
})

export const autodetectShouldSetCurrentDatasetAtom = atom<boolean>({
key: 'autodetectShouldSetCurrentDatasetAtom',
default: false,
})

0 comments on commit b3c410d

Please sign in to comment.