Skip to content

Commit e01acda

Browse files
author
Jonas Kellerer
committed
feat: add lineage queries for nextstrain, nextclade and gisaid
1 parent 217704e commit e01acda

File tree

5 files changed

+150
-0
lines changed

5 files changed

+150
-0
lines changed

lapis2/build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ dependencies {
3636
}
3737
testImplementation 'com.ninja-squad:springmockk:4.0.2'
3838
testImplementation 'org.mock-server:mockserver-netty:5.15.0'
39+
implementation "org.jetbrains.kotlin:kotlin-stdlib"
3940
}
4041

4142

lapis2/src/main/antlr/org/genspectrum/lapis/model/variantqueryparser/VariantQuery.g4

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,12 @@ single:
1616
nucleotide_mutation
1717
| pangolineage_query
1818
| n_of_query
19+
| nucleotide_insertion
20+
| aa_mutation
21+
| aa_insertion
22+
| nextclade_pangolineage_query
23+
| nextstrain_clade_lineage_query
24+
| gisaid_clade_lineage_query
1925
;
2026

2127
nucleotide_mutation : nucleotide_symbol? position ambigous_nucleotide_symbol?;
@@ -34,6 +40,30 @@ n_of_match_exactly: 'EXACTLY-';
3440
n_of_number_of_matchers: NUMBER+;
3541
n_of_exprs: expr (',' expr)*;
3642

43+
nucleotide_insertion: 'ins_' position ':' (ambigous_nucleotide_symbol | '?')+;
44+
45+
aa_mutation: gene ':' aa_symbol? position ambigous_aa_symbol?;
46+
aa_symbol: A | R | N | D | C | E | Q | G | H | I | L | K | M | F | P | S | T | W | Y | V | ASTERISK;
47+
ambigous_aa_symbol: aa_symbol | X | MINUS | DOT;
48+
gene: covid_gene;
49+
covid_gene : E | M | N | S | ORF;
50+
51+
aa_insertion: 'ins_' gene ':' (ambigous_aa_symbol | '?')+;
52+
53+
nextclade_pangolineage_query: nextclade_pango_lineage_prefix pangolineage_query;
54+
nextclade_pango_lineage_prefix: 'nextcladePangoLineage:';
55+
56+
nextstrain_clade_lineage_query: nextstrain_clade_prefix nextstrain_clade_query;
57+
nextstrain_clade_prefix: 'nextstrainClade:';
58+
nextstrain_clade_query: NUMBER NUMBER nextstrain_clade_character | 'RECOMBINANT';
59+
nextstrain_clade_character: A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z;
60+
61+
gisaid_clade_lineage_query: gisaid_clade_prefix gisaid_clade_query;
62+
gisaid_clade_prefix: 'gisaid:';
63+
gisaid_clade_query: gisaid_clade_character gisaid_clade_character?;
64+
gisaid_clade_character: A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z;
65+
66+
3767
// lexer rules
3868

3969
A: 'A';
@@ -68,3 +98,5 @@ ASTERISK: '*';
6898

6999
NUMBER: [0-9];
70100
WHITESPACE: [ \r\n\t] -> skip;
101+
102+
ORF: 'ORF1A' | 'ORF1B' | 'ORF3A' | 'ORF6' | 'ORF7A' | 'ORF7B' | 'ORF8' | 'ORF9B';

lapis2/src/main/kotlin/org/genspectrum/lapis/controller/ExceptionHandler.kt

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,21 @@ class ExceptionHandler : ResponseEntityExceptionHandler() {
6565
),
6666
)
6767
}
68+
69+
@ExceptionHandler(NotImplementedError::class)
70+
fun handleNotImplementedError(e: NotImplementedError): ResponseEntity<String> {
71+
return ResponseEntity
72+
.status(HttpStatus.NOT_IMPLEMENTED)
73+
.contentType(MediaType.APPLICATION_JSON)
74+
.body(
75+
jacksonObjectMapper().writeValueAsString(
76+
LapisHttpErrorResponse(
77+
"Not implemented",
78+
"${e.message}",
79+
),
80+
),
81+
)
82+
}
6883
}
6984

7085
data class LapisHttpErrorResponse(val title: String, val message: String)

lapis2/src/main/kotlin/org/genspectrum/lapis/model/VariantQueryCustomListener.kt

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,16 @@
11
package org.genspectrum.lapis.model
22

33
import VariantQueryBaseListener
4+
import VariantQueryParser.Aa_insertionContext
5+
import VariantQueryParser.Aa_mutationContext
46
import VariantQueryParser.AndContext
7+
import VariantQueryParser.Gisaid_clade_lineage_queryContext
58
import VariantQueryParser.MaybeContext
69
import VariantQueryParser.N_of_queryContext
10+
import VariantQueryParser.Nextclade_pangolineage_queryContext
11+
import VariantQueryParser.Nextstrain_clade_queryContext
712
import VariantQueryParser.NotContext
13+
import VariantQueryParser.Nucleotide_insertionContext
814
import VariantQueryParser.Nucleotide_mutationContext
915
import VariantQueryParser.OrContext
1016
import VariantQueryParser.Pangolineage_queryContext
@@ -82,4 +88,28 @@ class VariantQueryCustomListener : VariantQueryBaseListener(), ParseTreeListener
8288

8389
expressionStack.addLast(NOf(n, matchExactly, children.reversed()))
8490
}
91+
92+
override fun enterNucleotide_insertion(ctx: Nucleotide_insertionContext?) {
93+
throw NotImplementedError("Nucleotide insertions are not supported yet.")
94+
}
95+
96+
override fun enterAa_mutation(ctx: Aa_mutationContext?) {
97+
throw NotImplementedError("Amino acid mutations are not supported yet.")
98+
}
99+
100+
override fun enterAa_insertion(ctx: Aa_insertionContext?) {
101+
throw NotImplementedError("Amino acid insertions are not supported yet.")
102+
}
103+
104+
override fun enterNextclade_pangolineage_query(ctx: Nextclade_pangolineage_queryContext?) {
105+
throw NotImplementedError("Nextclade pango lineages are not supported yet.")
106+
}
107+
108+
override fun enterNextstrain_clade_query(ctx: Nextstrain_clade_queryContext?) {
109+
throw NotImplementedError("Nextstrain clade lineages are not supported yet.")
110+
}
111+
112+
override fun enterGisaid_clade_lineage_query(ctx: Gisaid_clade_lineage_queryContext?) {
113+
throw NotImplementedError("Gisaid clade lineages are not supported yet.")
114+
}
85115
}

lapis2/src/test/kotlin/org/genspectrum/lapis/model/VariantQueryFacadeTest.kt

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,78 @@ class VariantQueryFacadeTest {
216216
MatcherAssert.assertThat(result, Matchers.equalTo(expectedResult))
217217
}
218218

219+
@Test
220+
fun `given a variant variantQuery with a 'Insertion' expression the map should throw an error`() {
221+
val variantQuery = "ins_1234:GAG"
222+
223+
val exception = assertThrows<NotImplementedError> { underTest.map(variantQuery) }
224+
225+
MatcherAssert.assertThat(
226+
exception.message,
227+
Matchers.equalTo("Nucleotide insertions are not supported yet."),
228+
)
229+
}
230+
231+
@Test
232+
fun `given a valid variant variantQuery with a 'AA mutation' expression the map should throw an error`() {
233+
val variantQuery = "S:N501Y"
234+
235+
val exception = assertThrows<NotImplementedError> { underTest.map(variantQuery) }
236+
237+
MatcherAssert.assertThat(
238+
exception.message,
239+
Matchers.equalTo("Amino acid mutations are not supported yet."),
240+
)
241+
}
242+
243+
@Test
244+
fun `given a valid variant variantQuery with a 'AA insertion' expression the map should throw an error`() {
245+
val variantQuery = "ins_S:N501EPE"
246+
247+
val exception = assertThrows<NotImplementedError> { underTest.map(variantQuery) }
248+
249+
MatcherAssert.assertThat(
250+
exception.message,
251+
Matchers.equalTo("Amino acid insertions are not supported yet."),
252+
)
253+
}
254+
255+
@Test
256+
fun `given a valid variant variantQuery with a 'nextclade pango lineage' expression the map should throw an error`() {
257+
val variantQuery = "nextcladePangoLineage:BA.5*"
258+
259+
val exception = assertThrows<NotImplementedError> { underTest.map(variantQuery) }
260+
261+
MatcherAssert.assertThat(
262+
exception.message,
263+
Matchers.equalTo("Nextclade pango lineages are not supported yet."),
264+
)
265+
}
266+
267+
@Test
268+
fun `given a valid variant variantQuery with a 'Nextstrain clade lineage' expression the map should throw an error`() {
269+
val variantQuery = "nextstrainClade:22B"
270+
271+
val exception = assertThrows<NotImplementedError> { underTest.map(variantQuery) }
272+
273+
MatcherAssert.assertThat(
274+
exception.message,
275+
Matchers.equalTo("Nextstrain clade lineages are not supported yet."),
276+
)
277+
}
278+
279+
@Test
280+
fun `given a valid variant variantQuery with a 'Gisaid clade lineage' expression the map should throw an error`() {
281+
val variantQuery = "gisaid:AB"
282+
283+
val exception = assertThrows<NotImplementedError> { underTest.map(variantQuery) }
284+
285+
MatcherAssert.assertThat(
286+
exception.message,
287+
Matchers.equalTo("Gisaid clade lineages are not supported yet."),
288+
)
289+
}
290+
219291
@Test
220292
fun `given a variantQuery with a exact 'Nof' expression then map should return the corresponding SiloQuery`() {
221293
val variantQuery = "[exactly-3-of: 123A, 234T, 345G]"

0 commit comments

Comments
 (0)