feat(components): mutations over time: do not query mutations if explicit list is given#1100
feat(components): mutations over time: do not query mutations if explicit list is given#1100
Conversation
…icit list is given
This comment was marked as off-topic.
This comment was marked as off-topic.
9b2c7ef to
c89a459
Compare
c89a459 to
0196e75
Compare
|
Ohoh, this might create merge conflicts with the lazy loading... |
There was a problem hiding this comment.
Pull request overview
This PR optimizes the “mutations over time” data fetch by avoiding an extra (expensive) {aminoAcid,nucleotide}Mutations request when the caller already provides an explicit mutation list, and instead derives overall counts/proportions from the subsequent mutationsOverTime response.
Changes:
- Skip querying the full mutations list when
displayMutationsis provided; only query mutation codes whendisplayMutationsis absent. - Compute
overallMutationData(counts/proportions) frommutationsOverTimeper-datecount/coveragedata instead of a separate mutations endpoint call. - Update Vitest expectations and Storybook/snapshot artifacts to reflect the new aggregation behavior.
Reviewed changes
Copilot reviewed 6 out of 17 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| components/src/query/queryMutationsOverTime.ts | Removes overall mutations query for explicit lists; computes overall counts/proportions from over-time response; adds helper to query mutation codes only when needed. |
| components/src/query/queryMutationsOverTime.spec.ts | Updates expectations and removes now-unnecessary mutations endpoint mocks for explicit mutation list tests. |
| components/src/preact/mutationsOverTime/mutations-over-time.stories.tsx | Removes mocks for the now-skipped mutations call in stories with explicit displayMutations; adjusts initial interval to keep story stable. |
| components/src/lapisApi/lapisApi.ts | Adds clarifying comment about the shape of the 2D data array returned by mutationsOverTime. |
| components/tests/snapshots.spec.ts-snapshots/Mutations-over-time-Story-visualization-mutati-ddeb1-rtion-on-small-screen-should-match-screenshot-1-chromium-linux.png | Updated visual snapshot due to changed aggregation/output. |
| components/tests/snapshots.spec.ts-snapshots/Mutations-over-time-Story-visualization-mutati-c413d-ed-mutations-and-gaps-should-match-screenshot-1-chromium-linux.png | Updated visual snapshot due to changed aggregation/output. |
| components/tests/snapshots.spec.ts-snapshots/Mutations-over-time-Story-visualization-mutati-5715b-n-displayed-mutations-should-match-screenshot-1-chromium-linux.png | Updated visual snapshot due to changed aggregation/output. |
| components/tests/snapshots.spec.ts-snapshots/Mutations-over-time-Download-of-visualization-mutations-over-time--by-month-should-match-snapshot-1-firefox-linux.txt | Updated download snapshot rows/values due to changed aggregation/output. |
| components/tests/snapshots.spec.ts-snapshots/Mutations-over-time-Download-of-visualization-mutations-over-time--by-month-should-match-snapshot-1-chromium-linux.txt | Updated download snapshot rows/values due to changed aggregation/output. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| const mutationsToQuery = | ||
| displayMutations ?? | ||
| (await queryAllMutationCodes({ | ||
| lapisFilter, | ||
| requestedDateRanges, | ||
| sequenceType, | ||
| lapis, | ||
| lapisDateField, | ||
| signal, | ||
| })); | ||
| const sortedMutationCodes = mutationsToQuery | ||
| .map(parseMutationCode) | ||
| .sort((a, b) => sortSubstitutionsAndDeletions(a, b)) | ||
| .map((m) => m.code); |
There was a problem hiding this comment.
displayMutations values are now parsed via parseMutationCode for sorting. If a user provides an invalid mutation string, this will throw a generic Error and likely surface as an unhelpful runtime failure. Consider validating displayMutations up front and throwing a UserFacingError (or filtering out invalid codes) with a message that tells the user which entry is invalid and what formats are accepted.
There was a problem hiding this comment.
Hmm, it's not really a 'user' input per se, it's like if you misspelled the date field, it'll just error. IMO that's how we're doing things, so no change required?
Maybe we could add the parsing earlier, so we get the 'invalid component attributes' error, but I don't want to change more of the structure in the PR at the moment, because like Fabian said, we might already get merge conflicts the way it is.
But we could do it.
resolves #1099
Problem
We always query for all mutations in the date range, and also for all their counts and coverage. This is quite an expensive call to make, with the current 200 Million covid sequences, for the whole date range, this takes about 3 seconds. We make this call also if we only request a single mutation.
Solution
The call was done for two reasons:
For 1., we still query LAPIS to get the list; there is no way around this. But for 2., we can actually get all this data (counts, coverage) from the mutations-over-time call we make next. This PR does exactly that. Now for user provided mutation lists, we save the API call.
Tests, Screenshots
Some rows are now gone, some added, I skimmed it and it looks good to me. The changes are IMO because the calculations are sometimes slightly differently rounded? Or in some cases the data was edited manually anyways so two API calls don't correlate correctly.
PR Checklist
All necessary documentation has been adapted.