From 40fbd82d697ccaf3a6739c47235af734aa6680b7 Mon Sep 17 00:00:00 2001 From: Jonas Kellerer Date: Mon, 3 Jun 2024 08:12:53 +0200 Subject: [PATCH] fix(lapis): nucleotideInsertionContains correctly handles segment --- .github/workflows/lapis.yml | 11 ++++ .idea/runConfigurations/LapisOpen.xml | 13 +++++ .idea/runConfigurations/LapisProtected.xml | 13 +++++ .idea/runConfigurations/lapis_open.xml | 11 ---- .idea/runConfigurations/lapis_protected.xml | 11 ---- lapis-docs/.env.example | 4 +- lapis-docs/package.json | 2 +- lapis-docs/test-docker-compose.yml | 4 +- lapis-e2e/.gitignore | 1 + lapis-e2e/.prettierignore | 3 +- lapis-e2e/package.json | 8 ++- lapis-e2e/test/aggregated.spec.ts | 13 ++++- .../test/alignedNucleotideSequence.spec.ts | 15 +++++ lapis-e2e/test/aminoAcidSequence.spec.ts | 2 +- lapis-e2e/test/common.ts | 10 ++++ lapis-e2e/test/nucleotideInsertions.spec.ts | 16 +++++- lapis-e2e/test/nucleotideMutations.spec.ts | 20 ++++++- .../testData/multiSegmented/aa_insertions.tsv | 7 +++ .../testData/multiSegmented/gene_GPC.fasta | 12 ++++ .../testData/multiSegmented/gene_NP.fasta | 12 ++++ .../testData/multiSegmented/gene_RdRp.fasta | 12 ++++ .../multi_segmented_metadata.tsv | 7 +++ lapis-e2e/testData/multiSegmented/nuc_L.fasta | 12 ++++ lapis-e2e/testData/multiSegmented/nuc_M.fasta | 12 ++++ lapis-e2e/testData/multiSegmented/nuc_S.fasta | 12 ++++ .../multiSegmented/nuc_insertions.tsv | 7 +++ .../multiSegmented/preprocessingConfig.yaml | 2 + .../multiSegmented/reference_genomes.json | 30 ++++++++++ .../multiSegmented/testDatabaseConfig.yaml | 13 +++++ .../testData/multiSegmented/unaligned_L.fasta | 0 .../testData/multiSegmented/unaligned_M.fasta | 0 .../testData/multiSegmented/unaligned_S.fasta | 0 .../{ => singleSegmented}/aa_insertions.tsv | 0 .../{ => singleSegmented}/gene_E.fasta | 0 .../{ => singleSegmented}/gene_M.fasta | 0 .../{ => singleSegmented}/gene_N.fasta | 0 .../{ => singleSegmented}/gene_ORF1a.fasta | 0 .../{ => singleSegmented}/gene_ORF1b.fasta | 0 .../{ => singleSegmented}/gene_ORF3a.fasta | 0 .../{ => singleSegmented}/gene_ORF6.fasta | 0 .../{ => singleSegmented}/gene_ORF7a.fasta | 0 .../{ => singleSegmented}/gene_ORF7b.fasta | 0 .../{ => singleSegmented}/gene_ORF8.fasta | 0 .../{ => singleSegmented}/gene_ORF9b.fasta | 0 .../{ => singleSegmented}/gene_S.fasta | 0 .../{ => singleSegmented}/nuc_insertions.tsv | 0 .../{ => singleSegmented}/nuc_main.fasta | 0 .../pangolineage_alias.json | 0 .../preprocessingConfig.yaml | 0 .../protectedTestDatabaseConfig.yaml | 0 .../reference_genomes.json | 0 .../small_metadata_set.tsv | 0 .../testDatabaseConfig.yaml | 0 .../unaligned_main.fasta | 0 .../partition_id=0/data_0.parquet | Bin 4339 -> 0 bytes .../partition_id=1/data_0.parquet | Bin 10012 -> 0 bytes .../partition_id=10/data_0.parquet | Bin 4494 -> 0 bytes .../partition_id=2/data_0.parquet | Bin 15940 -> 0 bytes .../partition_id=3/data_0.parquet | Bin 44746 -> 0 bytes .../partition_id=4/data_0.parquet | Bin 10414 -> 0 bytes .../partition_id=5/data_0.parquet | Bin 8290 -> 0 bytes .../partition_id=6/data_0.parquet | Bin 8820 -> 0 bytes .../partition_id=7/data_0.parquet | Bin 3944 -> 0 bytes .../partition_id=8/data_0.parquet | Bin 7647 -> 0 bytes .../partition_id=9/data_0.parquet | Bin 7728 -> 0 bytes lapis/build.gradle | 32 ++++++++++- lapis/docker-compose.yml | 53 +++++++++++++++--- .../lapis/model/SiloFilterExpressionMapper.kt | 6 +- .../lapis/model/VariantQueryCustomListener.kt | 1 + .../org/genspectrum/lapis/silo/SiloQuery.kt | 4 +- .../model/SiloFilterExpressionMapperTest.kt | 2 +- .../lapis/model/VariantQueryFacadeTest.kt | 16 ++++-- .../genspectrum/lapis/silo/SiloQueryTest.kt | 32 +++++++++++ 73 files changed, 388 insertions(+), 53 deletions(-) create mode 100644 .idea/runConfigurations/LapisOpen.xml create mode 100644 .idea/runConfigurations/LapisProtected.xml delete mode 100644 .idea/runConfigurations/lapis_open.xml delete mode 100644 .idea/runConfigurations/lapis_protected.xml create mode 100644 lapis-e2e/testData/multiSegmented/aa_insertions.tsv create mode 100644 lapis-e2e/testData/multiSegmented/gene_GPC.fasta create mode 100644 lapis-e2e/testData/multiSegmented/gene_NP.fasta create mode 100644 lapis-e2e/testData/multiSegmented/gene_RdRp.fasta create mode 100644 lapis-e2e/testData/multiSegmented/multi_segmented_metadata.tsv create mode 100644 lapis-e2e/testData/multiSegmented/nuc_L.fasta create mode 100644 lapis-e2e/testData/multiSegmented/nuc_M.fasta create mode 100644 lapis-e2e/testData/multiSegmented/nuc_S.fasta create mode 100644 lapis-e2e/testData/multiSegmented/nuc_insertions.tsv create mode 100644 lapis-e2e/testData/multiSegmented/preprocessingConfig.yaml create mode 100644 lapis-e2e/testData/multiSegmented/reference_genomes.json create mode 100644 lapis-e2e/testData/multiSegmented/testDatabaseConfig.yaml create mode 100644 lapis-e2e/testData/multiSegmented/unaligned_L.fasta create mode 100644 lapis-e2e/testData/multiSegmented/unaligned_M.fasta create mode 100644 lapis-e2e/testData/multiSegmented/unaligned_S.fasta rename lapis-e2e/testData/{ => singleSegmented}/aa_insertions.tsv (100%) rename lapis-e2e/testData/{ => singleSegmented}/gene_E.fasta (100%) rename lapis-e2e/testData/{ => singleSegmented}/gene_M.fasta (100%) rename lapis-e2e/testData/{ => singleSegmented}/gene_N.fasta (100%) rename lapis-e2e/testData/{ => singleSegmented}/gene_ORF1a.fasta (100%) rename lapis-e2e/testData/{ => singleSegmented}/gene_ORF1b.fasta (100%) rename lapis-e2e/testData/{ => singleSegmented}/gene_ORF3a.fasta (100%) rename lapis-e2e/testData/{ => singleSegmented}/gene_ORF6.fasta (100%) rename lapis-e2e/testData/{ => singleSegmented}/gene_ORF7a.fasta (100%) rename lapis-e2e/testData/{ => singleSegmented}/gene_ORF7b.fasta (100%) rename lapis-e2e/testData/{ => singleSegmented}/gene_ORF8.fasta (100%) rename lapis-e2e/testData/{ => singleSegmented}/gene_ORF9b.fasta (100%) rename lapis-e2e/testData/{ => singleSegmented}/gene_S.fasta (100%) rename lapis-e2e/testData/{ => singleSegmented}/nuc_insertions.tsv (100%) rename lapis-e2e/testData/{ => singleSegmented}/nuc_main.fasta (100%) rename lapis-e2e/testData/{ => singleSegmented}/pangolineage_alias.json (100%) rename lapis-e2e/testData/{ => singleSegmented}/preprocessingConfig.yaml (100%) rename lapis-e2e/testData/{ => singleSegmented}/protectedTestDatabaseConfig.yaml (100%) rename lapis-e2e/testData/{ => singleSegmented}/reference_genomes.json (100%) rename lapis-e2e/testData/{ => singleSegmented}/small_metadata_set.tsv (100%) rename lapis-e2e/testData/{ => singleSegmented}/testDatabaseConfig.yaml (100%) rename lapis-e2e/testData/{ => singleSegmented}/unaligned_main.fasta (100%) delete mode 100644 lapis-e2e/testData/temp/unaligned_nuc_main/partition_id=0/data_0.parquet delete mode 100644 lapis-e2e/testData/temp/unaligned_nuc_main/partition_id=1/data_0.parquet delete mode 100644 lapis-e2e/testData/temp/unaligned_nuc_main/partition_id=10/data_0.parquet delete mode 100644 lapis-e2e/testData/temp/unaligned_nuc_main/partition_id=2/data_0.parquet delete mode 100644 lapis-e2e/testData/temp/unaligned_nuc_main/partition_id=3/data_0.parquet delete mode 100644 lapis-e2e/testData/temp/unaligned_nuc_main/partition_id=4/data_0.parquet delete mode 100644 lapis-e2e/testData/temp/unaligned_nuc_main/partition_id=5/data_0.parquet delete mode 100644 lapis-e2e/testData/temp/unaligned_nuc_main/partition_id=6/data_0.parquet delete mode 100644 lapis-e2e/testData/temp/unaligned_nuc_main/partition_id=7/data_0.parquet delete mode 100644 lapis-e2e/testData/temp/unaligned_nuc_main/partition_id=8/data_0.parquet delete mode 100644 lapis-e2e/testData/temp/unaligned_nuc_main/partition_id=9/data_0.parquet diff --git a/.github/workflows/lapis.yml b/.github/workflows/lapis.yml index c7f193c38..9f8b6fd6d 100644 --- a/.github/workflows/lapis.yml +++ b/.github/workflows/lapis.yml @@ -91,6 +91,12 @@ jobs: arguments: generateOpenApiDocs -PopennessLevel=protected build-root-directory: lapis + - name: Build OpenAPI Spec Multi segmented + uses: gradle/actions/setup-gradle@v3 + with: + arguments: generateOpenApiDocs -Psegmented=true + build-root-directory: lapis + - name: Cache .npm uses: actions/cache@v4 with: @@ -109,6 +115,10 @@ jobs: run: npm run generateLapisClientProtected working-directory: lapis-e2e + - name: Generate Lapis Client Multi Segmented + run: npm run generateLapisClientMultiSegmented + working-directory: lapis-e2e + - name: Check Format run: npm run check-format working-directory: lapis-e2e @@ -152,6 +162,7 @@ jobs: docker compose logs silo > e2e-logs/silo.log docker compose logs lapisOpen > e2e-logs/lapisOpen.log docker compose logs lapisProtected > e2e-logs/lapisProtected.log + docker compose logs lapisMultiSegmented > e2e-logs/lapisMultiSegmented.log env: SILO_TAG: latest LAPIS_TAG: ${{ steps.lapisBranchTag.outputs.lapisTag }} diff --git a/.idea/runConfigurations/LapisOpen.xml b/.idea/runConfigurations/LapisOpen.xml new file mode 100644 index 000000000..9e0575f9d --- /dev/null +++ b/.idea/runConfigurations/LapisOpen.xml @@ -0,0 +1,13 @@ + + + + \ No newline at end of file diff --git a/.idea/runConfigurations/LapisProtected.xml b/.idea/runConfigurations/LapisProtected.xml new file mode 100644 index 000000000..2a4ed3b1f --- /dev/null +++ b/.idea/runConfigurations/LapisProtected.xml @@ -0,0 +1,13 @@ + + + + \ No newline at end of file diff --git a/.idea/runConfigurations/lapis_open.xml b/.idea/runConfigurations/lapis_open.xml deleted file mode 100644 index 829d85f77..000000000 --- a/.idea/runConfigurations/lapis_open.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - \ No newline at end of file diff --git a/.idea/runConfigurations/lapis_protected.xml b/.idea/runConfigurations/lapis_protected.xml deleted file mode 100644 index 9c5d9d44b..000000000 --- a/.idea/runConfigurations/lapis_protected.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - \ No newline at end of file diff --git a/lapis-docs/.env.example b/lapis-docs/.env.example index 953a6e400..6b05707d0 100644 --- a/lapis-docs/.env.example +++ b/lapis-docs/.env.example @@ -1,4 +1,4 @@ # Create a .env file with this input might NOT work. You might need to properly set CONFIG_FILE as an # environment variable. -CONFIG_FILE=../lapis-e2e/testData/testDatabaseConfig.yaml -REFERENCE_GENOMES_FILE=../lapis-e2e/testData/reference_genomes.json +CONFIG_FILE=../lapis-e2e/testData/singleSegmented/testDatabaseConfig.yaml +REFERENCE_GENOMES_FILE=../lapis-e2e/testData/singleSegmented/reference_genomes.json diff --git a/lapis-docs/package.json b/lapis-docs/package.json index 0ee868047..4a0d68f5f 100644 --- a/lapis-docs/package.json +++ b/lapis-docs/package.json @@ -10,7 +10,7 @@ "astro": "astro", "check-format": "prettier --check \"**/*.{ts,tsx,json,astro,md,mdx,mjs,cjs}\"", "format": "prettier --write \"**/*.{ts,tsx,json,astro,md,mdx,mjs,cjs}\"", - "check-types": "CONFIG_FILE=../lapis-e2e/testData/testDatabaseConfig.yaml astro sync && tsc --noEmit", + "check-types": "CONFIG_FILE=../lapis-e2e/testData/singleSegmented/testDatabaseConfig.yaml astro sync && tsc --noEmit", "e2e": "playwright test" }, "dependencies": { diff --git a/lapis-docs/test-docker-compose.yml b/lapis-docs/test-docker-compose.yml index 692c3a2fb..a7576a2e2 100644 --- a/lapis-docs/test-docker-compose.yml +++ b/lapis-docs/test-docker-compose.yml @@ -5,8 +5,8 @@ services: ports: - "4321:3000" volumes: - - ../lapis-e2e/testData/testDatabaseConfig.yaml:/config/database_config.yaml - - ../lapis-e2e/testData/reference_genomes.json:/config/reference_genomes.json + - ../lapis-e2e/testData/singleSegmented/testDatabaseConfig.yaml:/config/database_config.yaml + - ../lapis-e2e/testData/singleSegmented/reference_genomes.json:/config/reference_genomes.json environment: LAPIS_URL: http://localhost:8090 BASE_URL: /docs/ diff --git a/lapis-e2e/.gitignore b/lapis-e2e/.gitignore index c94e026c0..1ca49b7fe 100644 --- a/lapis-e2e/.gitignore +++ b/lapis-e2e/.gitignore @@ -3,3 +3,4 @@ node_modules/ **/output/ **/logs/ +**/temp/ diff --git a/lapis-e2e/.prettierignore b/lapis-e2e/.prettierignore index e0f97514e..df9332181 100644 --- a/lapis-e2e/.prettierignore +++ b/lapis-e2e/.prettierignore @@ -1,2 +1,3 @@ /test/lapisClient -/test/lapisClientProtected \ No newline at end of file +/test/lapisClientProtected +/test/lapisClientMultiSegmented \ No newline at end of file diff --git a/lapis-e2e/package.json b/lapis-e2e/package.json index c268d9473..b41814ceb 100644 --- a/lapis-e2e/package.json +++ b/lapis-e2e/package.json @@ -5,13 +5,17 @@ "scripts": { "test": "mocha --exit", "generateLapisClient": "npm run runOpenApiGenerator && npm run copyGeneratedFiles && npm run cleanUpGeneratedFiles", - "runOpenApiGenerator": "openapi-generator-cli generate -i ../lapis/lapis-openapi.json -g typescript-fetch -o generated-sources", + "runOpenApiGenerator": "openapi-generator-cli generate -i ../lapis/lapis-openapi-single-segmented.json -g typescript-fetch -o generated-sources", "copyGeneratedFiles": "mkdir -p test/lapisClient && cp generated-sources/index.ts generated-sources/runtime.ts test/lapisClient && cp -r generated-sources/apis generated-sources/models test/lapisClient", "generateLapisClientProtected": "npm run runOpenApiGeneratorProtected && npm run copyGeneratedFilesProtected && npm run cleanUpGeneratedFilesProtected", - "runOpenApiGeneratorProtected": "openapi-generator-cli generate -i ../lapis/lapis-openapi-protected.json -g typescript-fetch -o generated-sources-protected", + "runOpenApiGeneratorProtected": "openapi-generator-cli generate -i ../lapis/lapis-openapi-single-segmented-protected.json -g typescript-fetch -o generated-sources-protected", "copyGeneratedFilesProtected": "mkdir -p test/lapisClientProtected && cp generated-sources-protected/index.ts generated-sources-protected/runtime.ts test/lapisClientProtected && cp -r generated-sources-protected/apis generated-sources-protected/models test/lapisClientProtected", + "generateLapisClientMultiSegmented": "npm run runOpenApiGeneratorMultiSegmented && npm run copyGeneratedFilesMultiSegmented && npm run cleanUpGeneratedFilesMultiSegmented", + "runOpenApiGeneratorMultiSegmented": "openapi-generator-cli generate -i ../lapis/lapis-openapi-multi-segmented.json -g typescript-fetch -o generated-sources-multi-segmented", + "copyGeneratedFilesMultiSegmented": "mkdir -p test/lapisClientMultiSegmented && cp generated-sources-multi-segmented/index.ts generated-sources-multi-segmented/runtime.ts test/lapisClientMultiSegmented && cp -r generated-sources-multi-segmented/apis generated-sources-multi-segmented/models test/lapisClientMultiSegmented", "cleanUpGeneratedFiles": "rm -rf generated-sources", "cleanUpGeneratedFilesProtected": "rm -rf generated-sources-protected", + "cleanUpGeneratedFilesMultiSegmented": "rm -rf generated-sources-multi-segmented", "check-format": "prettier --check .", "format": "prettier --write ." }, diff --git a/lapis-e2e/test/aggregated.spec.ts b/lapis-e2e/test/aggregated.spec.ts index a58ce6033..107de5e82 100644 --- a/lapis-e2e/test/aggregated.spec.ts +++ b/lapis-e2e/test/aggregated.spec.ts @@ -1,5 +1,5 @@ import { expect } from 'chai'; -import { basePath, lapisClient } from './common'; +import { basePath, lapisClient, lapisClientMultiSegmented } from './common'; import fs from 'fs'; import { AggregatedPostRequest, AggregatedResponse } from './lapisClient'; @@ -46,6 +46,17 @@ describe('The /aggregated endpoint', () => { }) ); + it('should correcty handle aggregated request with multiple segments', async () => { + const result = await lapisClientMultiSegmented.postAggregated1({ + aggregatedPostRequest: { + nucleotideMutations: ['L:T1A', 'M:T1C'], + }, + }); + + expect(result.data).to.have.length(1); + expect(result.data[0]).to.have.property('count', 1); + }); + it('should correctly handle multiple mutation requests in GET requests', async () => { const urlParams = new URLSearchParams({ nucleotideMutations: 'T1-,A23062T', diff --git a/lapis-e2e/test/alignedNucleotideSequence.spec.ts b/lapis-e2e/test/alignedNucleotideSequence.spec.ts index 4116787e7..9595d6f95 100644 --- a/lapis-e2e/test/alignedNucleotideSequence.spec.ts +++ b/lapis-e2e/test/alignedNucleotideSequence.spec.ts @@ -2,6 +2,7 @@ import { expect } from 'chai'; import { basePath, expectIsZstdEncoded, + lapisMultiSegmentedSequenceController, lapisSingleSegmentedSequenceController, sequenceData, } from './common'; @@ -20,6 +21,20 @@ describe('The /alignedNucleotideSequence endpoint', () => { expect(sequences[0]).to.have.length(29903); }); + it('should return aligned nucleotide sequences for multi segmented sequences', async () => { + const result = await lapisMultiSegmentedSequenceController.postAlignedNucleotideSequence({ + nucleotideSequenceRequest: { country: 'Switzerland' }, + segment: 'M', + }); + + const { primaryKeys, sequences } = sequenceData(result); + + expect(primaryKeys).to.have.length(6); + expect(sequences).to.have.length(6); + expect(primaryKeys[0]).to.equal('>key_5'); + expect(sequences[0]).to.equal('TGGG'); + }); + it('should order ascending by specified fields', async () => { const result = await lapisSingleSegmentedSequenceController.postAlignedNucleotideSequence({ nucleotideSequenceRequest: { orderBy: [{ field: 'primaryKey', type: 'ascending' }] }, diff --git a/lapis-e2e/test/aminoAcidSequence.spec.ts b/lapis-e2e/test/aminoAcidSequence.spec.ts index 7502530ce..716c96ef0 100644 --- a/lapis-e2e/test/aminoAcidSequence.spec.ts +++ b/lapis-e2e/test/aminoAcidSequence.spec.ts @@ -1,5 +1,5 @@ import { expect } from 'chai'; -import { basePath, lapisClient, sequenceData } from './common'; +import { lapisClient, sequenceData } from './common'; describe('The /alignedAminoAcidSequence endpoint', () => { it('should return amino acid sequences for Switzerland', async () => { diff --git a/lapis-e2e/test/common.ts b/lapis-e2e/test/common.ts index f90cf4064..0c28a51c1 100644 --- a/lapis-e2e/test/common.ts +++ b/lapis-e2e/test/common.ts @@ -4,15 +4,18 @@ import { Middleware, SingleSegmentedSequenceControllerApi, } from './lapisClient'; +import { LapisControllerApi as LapisControllerApiMultiSegmented } from './lapisClientMultiSegmented'; import { expect } from 'chai'; import { LapisControllerApi as LapisControllerApiProtected, Configuration as ConfigurationProtected, } from './lapisClientProtected'; +import { MultiSegmentedSequenceControllerApi } from './lapisClientMultiSegmented'; export const basePath = 'http://localhost:8090'; export const basePathProtected = 'http://localhost:8092'; +export const basePathMultiSegmented = 'http://localhost:8094'; const middleware: Middleware = { onError: errorContext => { @@ -40,11 +43,18 @@ export const lapisClient = new LapisControllerApi(new Configuration({ basePath } export const lapisClientProtected = new LapisControllerApiProtected( new ConfigurationProtected({ basePath: basePathProtected }) ).withMiddleware(middleware); +export const lapisClientMultiSegmented = new LapisControllerApiMultiSegmented( + new Configuration({ basePath: basePathMultiSegmented }) +).withMiddleware(middleware); export const lapisSingleSegmentedSequenceController = new SingleSegmentedSequenceControllerApi( new Configuration({ basePath }) ).withMiddleware(middleware); +export const lapisMultiSegmentedSequenceController = new MultiSegmentedSequenceControllerApi( + new Configuration({ basePath: basePathMultiSegmented }) +).withMiddleware(middleware); + export function sequenceData(serverResponse: string) { const lines = serverResponse.split('\n').filter(line => line.length > 0); const primaryKeys = lines.filter(line => line.startsWith('>')); diff --git a/lapis-e2e/test/nucleotideInsertions.spec.ts b/lapis-e2e/test/nucleotideInsertions.spec.ts index eaaa157e9..e31318e48 100644 --- a/lapis-e2e/test/nucleotideInsertions.spec.ts +++ b/lapis-e2e/test/nucleotideInsertions.spec.ts @@ -1,5 +1,5 @@ import { expect } from 'chai'; -import { basePath, lapisClient } from './common'; +import { basePath, lapisClient, lapisClientMultiSegmented } from './common'; describe('The /nucleotideInsertions endpoint', () => { let someInsertion = 'ins_25701:CCC'; @@ -18,6 +18,20 @@ describe('The /nucleotideInsertions endpoint', () => { expect(specificInsertion?.sequenceName).to.be.undefined; }); + it('should return nucleotide insertions for multi segmented sequences', async () => { + const result = await lapisClientMultiSegmented.postNucleotideInsertions1({ + insertionsRequest: { country: 'Switzerland' }, + }); + + expect(result.data).to.have.length(2); + + const insertionsFirstSegment = result.data.find(mutationData => mutationData.insertion === 'ins_L:1:AB'); + expect(insertionsFirstSegment?.count).to.equal(2); + + const insertionsSecondSegment = result.data.find(mutationData => mutationData.insertion === 'ins_M:2:BC'); + expect(insertionsSecondSegment?.count).to.equal(1); + }); + it('should order by specified fields', async () => { const ascendingOrderedResult = await lapisClient.postNucleotideInsertions1({ insertionsRequest: { diff --git a/lapis-e2e/test/nucleotideMutations.spec.ts b/lapis-e2e/test/nucleotideMutations.spec.ts index 8d23168e9..f089d16a2 100644 --- a/lapis-e2e/test/nucleotideMutations.spec.ts +++ b/lapis-e2e/test/nucleotideMutations.spec.ts @@ -1,5 +1,5 @@ import { expect } from 'chai'; -import { basePath, lapisClient } from './common'; +import { basePath, lapisClient, lapisClientMultiSegmented } from './common'; describe('The /nucleotideMutations endpoint', () => { let mutationWithLessThan10PercentProportion = 'C19220T'; @@ -29,6 +29,24 @@ describe('The /nucleotideMutations endpoint', () => { expect(commonMutationProportion?.position).to.be.equal(28280); }); + it('should return mutations proportions for multi segmented', async () => { + const result = await lapisClientMultiSegmented.postNucleotideMutations1({ + sequenceFiltersWithMinProportion: { country: 'Switzerland' }, + }); + + expect(result.data).to.have.length(2); + + const mutationProportionOnFirstSegment = result.data.find( + mutationData => mutationData.mutation === 'L:T1A' + ); + expect(mutationProportionOnFirstSegment?.count).to.equal(2); + + const mutationProportionOnSecondSegment = result.data.find( + mutationData => mutationData.mutation === 'M:T1C' + ); + expect(mutationProportionOnSecondSegment?.count).to.equal(1); + }); + it('should return mutation proportions for Switzerland with minProportion 0.5', async () => { const result = await lapisClient.postNucleotideMutations1({ sequenceFiltersWithMinProportion: { diff --git a/lapis-e2e/testData/multiSegmented/aa_insertions.tsv b/lapis-e2e/testData/multiSegmented/aa_insertions.tsv new file mode 100644 index 000000000..ead67f527 --- /dev/null +++ b/lapis-e2e/testData/multiSegmented/aa_insertions.tsv @@ -0,0 +1,7 @@ +primaryKey RdRp NP GPC +key_0 [] [] [] +key_1 [] [] [] +key_2 [] [] [] +key_3 [] [] [] +key_4 [] [] [] +key_5 [] [] [] diff --git a/lapis-e2e/testData/multiSegmented/gene_GPC.fasta b/lapis-e2e/testData/multiSegmented/gene_GPC.fasta new file mode 100644 index 000000000..17cdb7f92 --- /dev/null +++ b/lapis-e2e/testData/multiSegmented/gene_GPC.fasta @@ -0,0 +1,12 @@ +>key_0 +MS* +>key_1 +MS* +>key_2 +MS* +>key_3 +MS* +>key_4 +MS* +>key_5 +MS* \ No newline at end of file diff --git a/lapis-e2e/testData/multiSegmented/gene_NP.fasta b/lapis-e2e/testData/multiSegmented/gene_NP.fasta new file mode 100644 index 000000000..e68095f73 --- /dev/null +++ b/lapis-e2e/testData/multiSegmented/gene_NP.fasta @@ -0,0 +1,12 @@ +>key_0 +MEN* +>key_1 +MEN* +>key_2 +MEN* +>key_3 +MEN* +>key_4 +MEN* +>key_5 +MEN* \ No newline at end of file diff --git a/lapis-e2e/testData/multiSegmented/gene_RdRp.fasta b/lapis-e2e/testData/multiSegmented/gene_RdRp.fasta new file mode 100644 index 000000000..8d39d7b83 --- /dev/null +++ b/lapis-e2e/testData/multiSegmented/gene_RdRp.fasta @@ -0,0 +1,12 @@ +>key_0 +MDFL* +>key_1 +MDFL* +>key_2 +MDFL* +>key_3 +MDFL* +>key_4 +MDFL* +>key_5 +MDFL* \ No newline at end of file diff --git a/lapis-e2e/testData/multiSegmented/multi_segmented_metadata.tsv b/lapis-e2e/testData/multiSegmented/multi_segmented_metadata.tsv new file mode 100644 index 000000000..d4286cd5c --- /dev/null +++ b/lapis-e2e/testData/multiSegmented/multi_segmented_metadata.tsv @@ -0,0 +1,7 @@ +primaryKey date country +key_0 2021-03-18 Switzerland +key_1 2021-04-13 Switzerland +key_2 2021-04-25 Switzerland +key_3 2021-04-13 Switzerland +key_4 2021-03-19 Switzerland +key_5 Switzerland \ No newline at end of file diff --git a/lapis-e2e/testData/multiSegmented/nuc_L.fasta b/lapis-e2e/testData/multiSegmented/nuc_L.fasta new file mode 100644 index 000000000..b17d62d75 --- /dev/null +++ b/lapis-e2e/testData/multiSegmented/nuc_L.fasta @@ -0,0 +1,12 @@ +>key_0 +ACTCT +>key_1 +ACTCT +>key_2 +TCTCT +>key_3 +TCTCT +>key_4 +TCTCT +>key_5 +TCTCT \ No newline at end of file diff --git a/lapis-e2e/testData/multiSegmented/nuc_M.fasta b/lapis-e2e/testData/multiSegmented/nuc_M.fasta new file mode 100644 index 000000000..fdd2d8745 --- /dev/null +++ b/lapis-e2e/testData/multiSegmented/nuc_M.fasta @@ -0,0 +1,12 @@ +>key_0 +CGGG +>key_1 +TGGG +>key_2 +TGGG +>key_3 +TGGG +>key_4 +TGGG +>key_5 +TGGG \ No newline at end of file diff --git a/lapis-e2e/testData/multiSegmented/nuc_S.fasta b/lapis-e2e/testData/multiSegmented/nuc_S.fasta new file mode 100644 index 000000000..dcb4c9848 --- /dev/null +++ b/lapis-e2e/testData/multiSegmented/nuc_S.fasta @@ -0,0 +1,12 @@ +>key_0 +AAA +>key_1 +AAA +>key_2 +AAA +>key_3 +AAA +>key_4 +AAA +>key_5 +AAA \ No newline at end of file diff --git a/lapis-e2e/testData/multiSegmented/nuc_insertions.tsv b/lapis-e2e/testData/multiSegmented/nuc_insertions.tsv new file mode 100644 index 000000000..ec32bcf03 --- /dev/null +++ b/lapis-e2e/testData/multiSegmented/nuc_insertions.tsv @@ -0,0 +1,7 @@ +primaryKey L M S +key_0 [] [] [] +key_1 [1:AB] [] [] +key_2 [1:AB] [] [] +key_3 [] [2:BC] [] +key_4 [] [] [] +key_5 [] [] [] diff --git a/lapis-e2e/testData/multiSegmented/preprocessingConfig.yaml b/lapis-e2e/testData/multiSegmented/preprocessingConfig.yaml new file mode 100644 index 000000000..5b5dba652 --- /dev/null +++ b/lapis-e2e/testData/multiSegmented/preprocessingConfig.yaml @@ -0,0 +1,2 @@ +metadataFilename: multi_segmented_metadata.tsv +referenceGenomeFilename: reference_genomes.json diff --git a/lapis-e2e/testData/multiSegmented/reference_genomes.json b/lapis-e2e/testData/multiSegmented/reference_genomes.json new file mode 100644 index 000000000..b4f6753a6 --- /dev/null +++ b/lapis-e2e/testData/multiSegmented/reference_genomes.json @@ -0,0 +1,30 @@ +{ + "nucleotideSequences": [ + { + "name": "L", + "sequence": "TCTCT" + }, + { + "name": "M", + "sequence": "TGGG" + }, + { + "name": "S", + "sequence": "AAA" + } + ], + "genes": [ + { + "name": "RdRp", + "sequence": "MDFL*" + }, + { + "name": "GPC", + "sequence": "MS*" + }, + { + "name": "NP", + "sequence": "MEN*" + } + ] +} diff --git a/lapis-e2e/testData/multiSegmented/testDatabaseConfig.yaml b/lapis-e2e/testData/multiSegmented/testDatabaseConfig.yaml new file mode 100644 index 000000000..25e9f38df --- /dev/null +++ b/lapis-e2e/testData/multiSegmented/testDatabaseConfig.yaml @@ -0,0 +1,13 @@ +schema: + instanceName: crimean-congo-hemorrhagic-fever-virus-multi-segmented-test + opennessLevel: OPEN + metadata: + - name: primaryKey + type: string + - name: date + type: date + - name: country + type: string + generateIndex: true + primaryKey: primaryKey + dateToSortBy: date diff --git a/lapis-e2e/testData/multiSegmented/unaligned_L.fasta b/lapis-e2e/testData/multiSegmented/unaligned_L.fasta new file mode 100644 index 000000000..e69de29bb diff --git a/lapis-e2e/testData/multiSegmented/unaligned_M.fasta b/lapis-e2e/testData/multiSegmented/unaligned_M.fasta new file mode 100644 index 000000000..e69de29bb diff --git a/lapis-e2e/testData/multiSegmented/unaligned_S.fasta b/lapis-e2e/testData/multiSegmented/unaligned_S.fasta new file mode 100644 index 000000000..e69de29bb diff --git a/lapis-e2e/testData/aa_insertions.tsv b/lapis-e2e/testData/singleSegmented/aa_insertions.tsv similarity index 100% rename from lapis-e2e/testData/aa_insertions.tsv rename to lapis-e2e/testData/singleSegmented/aa_insertions.tsv diff --git a/lapis-e2e/testData/gene_E.fasta b/lapis-e2e/testData/singleSegmented/gene_E.fasta similarity index 100% rename from lapis-e2e/testData/gene_E.fasta rename to lapis-e2e/testData/singleSegmented/gene_E.fasta diff --git a/lapis-e2e/testData/gene_M.fasta b/lapis-e2e/testData/singleSegmented/gene_M.fasta similarity index 100% rename from lapis-e2e/testData/gene_M.fasta rename to lapis-e2e/testData/singleSegmented/gene_M.fasta diff --git a/lapis-e2e/testData/gene_N.fasta b/lapis-e2e/testData/singleSegmented/gene_N.fasta similarity index 100% rename from lapis-e2e/testData/gene_N.fasta rename to lapis-e2e/testData/singleSegmented/gene_N.fasta diff --git a/lapis-e2e/testData/gene_ORF1a.fasta b/lapis-e2e/testData/singleSegmented/gene_ORF1a.fasta similarity index 100% rename from lapis-e2e/testData/gene_ORF1a.fasta rename to lapis-e2e/testData/singleSegmented/gene_ORF1a.fasta diff --git a/lapis-e2e/testData/gene_ORF1b.fasta b/lapis-e2e/testData/singleSegmented/gene_ORF1b.fasta similarity index 100% rename from lapis-e2e/testData/gene_ORF1b.fasta rename to lapis-e2e/testData/singleSegmented/gene_ORF1b.fasta diff --git a/lapis-e2e/testData/gene_ORF3a.fasta b/lapis-e2e/testData/singleSegmented/gene_ORF3a.fasta similarity index 100% rename from lapis-e2e/testData/gene_ORF3a.fasta rename to lapis-e2e/testData/singleSegmented/gene_ORF3a.fasta diff --git a/lapis-e2e/testData/gene_ORF6.fasta b/lapis-e2e/testData/singleSegmented/gene_ORF6.fasta similarity index 100% rename from lapis-e2e/testData/gene_ORF6.fasta rename to lapis-e2e/testData/singleSegmented/gene_ORF6.fasta diff --git a/lapis-e2e/testData/gene_ORF7a.fasta b/lapis-e2e/testData/singleSegmented/gene_ORF7a.fasta similarity index 100% rename from lapis-e2e/testData/gene_ORF7a.fasta rename to lapis-e2e/testData/singleSegmented/gene_ORF7a.fasta diff --git a/lapis-e2e/testData/gene_ORF7b.fasta b/lapis-e2e/testData/singleSegmented/gene_ORF7b.fasta similarity index 100% rename from lapis-e2e/testData/gene_ORF7b.fasta rename to lapis-e2e/testData/singleSegmented/gene_ORF7b.fasta diff --git a/lapis-e2e/testData/gene_ORF8.fasta b/lapis-e2e/testData/singleSegmented/gene_ORF8.fasta similarity index 100% rename from lapis-e2e/testData/gene_ORF8.fasta rename to lapis-e2e/testData/singleSegmented/gene_ORF8.fasta diff --git a/lapis-e2e/testData/gene_ORF9b.fasta b/lapis-e2e/testData/singleSegmented/gene_ORF9b.fasta similarity index 100% rename from lapis-e2e/testData/gene_ORF9b.fasta rename to lapis-e2e/testData/singleSegmented/gene_ORF9b.fasta diff --git a/lapis-e2e/testData/gene_S.fasta b/lapis-e2e/testData/singleSegmented/gene_S.fasta similarity index 100% rename from lapis-e2e/testData/gene_S.fasta rename to lapis-e2e/testData/singleSegmented/gene_S.fasta diff --git a/lapis-e2e/testData/nuc_insertions.tsv b/lapis-e2e/testData/singleSegmented/nuc_insertions.tsv similarity index 100% rename from lapis-e2e/testData/nuc_insertions.tsv rename to lapis-e2e/testData/singleSegmented/nuc_insertions.tsv diff --git a/lapis-e2e/testData/nuc_main.fasta b/lapis-e2e/testData/singleSegmented/nuc_main.fasta similarity index 100% rename from lapis-e2e/testData/nuc_main.fasta rename to lapis-e2e/testData/singleSegmented/nuc_main.fasta diff --git a/lapis-e2e/testData/pangolineage_alias.json b/lapis-e2e/testData/singleSegmented/pangolineage_alias.json similarity index 100% rename from lapis-e2e/testData/pangolineage_alias.json rename to lapis-e2e/testData/singleSegmented/pangolineage_alias.json diff --git a/lapis-e2e/testData/preprocessingConfig.yaml b/lapis-e2e/testData/singleSegmented/preprocessingConfig.yaml similarity index 100% rename from lapis-e2e/testData/preprocessingConfig.yaml rename to lapis-e2e/testData/singleSegmented/preprocessingConfig.yaml diff --git a/lapis-e2e/testData/protectedTestDatabaseConfig.yaml b/lapis-e2e/testData/singleSegmented/protectedTestDatabaseConfig.yaml similarity index 100% rename from lapis-e2e/testData/protectedTestDatabaseConfig.yaml rename to lapis-e2e/testData/singleSegmented/protectedTestDatabaseConfig.yaml diff --git a/lapis-e2e/testData/reference_genomes.json b/lapis-e2e/testData/singleSegmented/reference_genomes.json similarity index 100% rename from lapis-e2e/testData/reference_genomes.json rename to lapis-e2e/testData/singleSegmented/reference_genomes.json diff --git a/lapis-e2e/testData/small_metadata_set.tsv b/lapis-e2e/testData/singleSegmented/small_metadata_set.tsv similarity index 100% rename from lapis-e2e/testData/small_metadata_set.tsv rename to lapis-e2e/testData/singleSegmented/small_metadata_set.tsv diff --git a/lapis-e2e/testData/testDatabaseConfig.yaml b/lapis-e2e/testData/singleSegmented/testDatabaseConfig.yaml similarity index 100% rename from lapis-e2e/testData/testDatabaseConfig.yaml rename to lapis-e2e/testData/singleSegmented/testDatabaseConfig.yaml diff --git a/lapis-e2e/testData/unaligned_main.fasta b/lapis-e2e/testData/singleSegmented/unaligned_main.fasta similarity index 100% rename from lapis-e2e/testData/unaligned_main.fasta rename to lapis-e2e/testData/singleSegmented/unaligned_main.fasta diff --git a/lapis-e2e/testData/temp/unaligned_nuc_main/partition_id=0/data_0.parquet b/lapis-e2e/testData/temp/unaligned_nuc_main/partition_id=0/data_0.parquet deleted file mode 100644 index f67d7c71f548861d2400be76715a01632ac1ac53..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4339 zcmeHLdpMM78-M3uW=w+_W0+ZkVa6ebGK@n@%@{2vO{#I0oL-+kY|XB^nu z3<&_C8A8Z_&Gxo_{s9jJH&XXw6$Poxv`wQcV>7e zR^#`@lz0?I-CFCo-rR*2_rPxkjG||_;-q~0Hodh%w+0%E%^ktjXYVyIRX-A%(Vu%s ziP8Y&R1N68#+FWK7%JZjajDS0G-pdQ4w^;S9V^nYtjdhd`)vwIt@6lfNVpFnA}^5( zpGDrdDbppRV*89W8~N(!PAC4>@$VzTxPFE>OunsF)@!+YqFCoE9J~G8pB$|T)(zd> zh0P?Vm-8{clyNu|-?YoVRPeUTt&ECaGm{D z?(o~G3{~C(zd04Rsowm;M2pEoIn!?!u%0_6vg(wN*Hm<~uSJQ{sivKOm|1<7Bd1sG zGD|o#7J$#V{KWX;eW`w@+$1C&zu5p$edpcLbo0v#8@-}~Yt}*>m`Gx9m7L$7Sh*3MJ{h7BHk4u{XzXLI=ae48bk_^agwdqS2dB&xUok!Ka8bzwEmiWYGRZ6Z+@ zsma3>7Dv?*(U}#x z?-oP4#yIZ}#LyY1HRaw2{i^o%mMW$tM)tzSo@*l!`oVV;=JR||bW4l8tEK}{Uv;t7FQ5v zFJZh4@y>F}Ah{Zv#iC)evc8pP#k;4*qeL@J8ajz6lseQ3F6$d4NAF?T&&TN)#s&O< z+t4F*2yx_eWmA;VCRlRAfSI<5kDd5FchDrVQ7PtL9QF`1Y!@zj8&+mW`~+`Y1B(h6 zz2U4ZC8=Qzgo%%3oi^tlK?b=p1I_$hfD@M{LQxCXiqX*v*BNxot$^D0HRhDYzNCSR zShCBxGsU{+gV&e5itdlmcy(VbJo^&IiZv>yM6P_89hfFyiBornY?|p;FIqjK5uab)fk&&`SmrTI3H#97DE0ci_i$M)G7jRs7}rU8w`y+E)7NTocz48^8IsBYcJ2YC zeRe&0be>a7C;J;#r%8x3gj_4-`sxWYpjy&VphrvS*N^TeG<~MXIT_#{^b2pu{?AwZ z#0`FYae2r?NG8Y*fwi?DR-Q!x3jiC(gImuhqNLSZq;bdXB4LI3XhN-?PEbT6ZATSS zYL#$c*kLjYfv5iRpqFXfH@^B+4iT=$9*oj)M5aAFdQX+*5i)EfOD2Zwi64|czFCKY zZ2MuaZP1-{Ni-I@Z85&uHu3QMQ4i-?ch7Nyi$5Mcowo)a8)LNkLq-4g8WXpqWUwp8))pYKlYL< z8usQqXBM#I_7**~oAR`uo$3hg+J9O0Mw^Y8Gux0Ut+kV+X6P&$EU^si#y6nzN}eLJ zLm8_#xEYskIbMKt+})c|QMmgz?F{WWARH)Ke3BWzGh@b2@x(*Ytuw4G$d2)%`Y^j5 zr;}o*6CRoC8blV!JlB>NS6*11)${bdB#_t+e+MIOyW5(9c5OsTReHjMK`wa*@5w4qrWPZU!cI(E6neE{~#Ywc@Z$0 zP$CSJT$;ejTs|V$XSZ-yu)n}7IKs~>$VV6q5a6H@Cd4N+To^9g6YM1vXwm>h42ev# z&;rN=42b}cmYoowiWtQ)h+-W?3uQrEwXEcp^qLXllz5vXP;kqnB||C zp(?(oYF&X?5QiZjtIz*2u*CE5ud?;4Z2cc)E0|)>qzJY|Efk=Gum*dqwG|MC1ONx{?~XqKYj+Wr diff --git a/lapis-e2e/testData/temp/unaligned_nuc_main/partition_id=1/data_0.parquet b/lapis-e2e/testData/temp/unaligned_nuc_main/partition_id=1/data_0.parquet deleted file mode 100644 index 15121e3a9b1c9b4da1da2b85963039ebd1c763a5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10012 zcmeHtWl&trw)QZ%4({#}bOuX+;O_1)xQF191Pku&!QC}jU~ngRu;9TR0>Ljw?sv{t zb?@JM{=8j#cdgyKYwfPutDg0&ep*#botpqa5C})$@rnTD#X=%L0szExfdBvi1rGhC zx3}~*;pXDv;o{{%1E7NNA$)v-5FQ)~O)xi)06&=jzvu9P`S>B=zd6frBq((JH*e#7 zSBhl+aA<-L05CUkKAL`at;z>%BBG+K?{7Kaa>8gG$DCGwD0fak^l; z4OKiYP!J-qN+Euj8rc4(rmB!vVx2#i_H$|FC{4MVlay~_sQU!Q&JL;#K@gjHVl!9S!B~~{-*;rnFm!J z4;2D1@I%CA9N!>mP={Rz&krjxTaro(d^abDm`brf{Aq7h7tmYv5!;B z68i!hh7f0z-h~cq^74C7BZEoJ-(6AU8}Rdg)A8Enx(Jwc_MHI^wjygA|CE+yHe!hk z+f)19gqn$4j;tvB{t~P*<8H0R&f$P0(C1e*DL&2f99gB4zZEek#Xevk7b>lpjsky$ zYJdxe89D_kPli-=e91vyz!ka=jt;HxC)UXod-dCPRL8{#q)l#Xd*G!j)F<2&9d8oG zF2$ENXbxxg-7UQ8qBMnNv{hIFR}20NFjxa4m9GrJx4ET!A$tseJNJ?yJHm|MfM%ZP@oR4$!hNj_HPF0-B3dROXtk7Vc=E^1dH|<^f znLiow3~KY8ONvkrGBF)ta|FdV$Y6jgZBtCrZh{z(3C4K~k;1IwKKP;E6Hgiw!=^uV z#inQgE;Q$4Q?+A~fH}AKT_it>4sqgx`JAx{eeUUJ|2_fVb8xcvAd0`+B=t9k)tPkt znx{?nrZtv+mRx)V{6S0pP^$yqtteY?`49XbLCyaeekK9NvxmuRa)BbBM=ZOcY867V-Mjk=`K7GEwzmB6fJvgt_Md4;sUkgCw`n= zsU62sPYCFy4gYG7f`&`>J$_(V11^6~R8Vk^xF_sm`k1xXwJElM)#wL2*PdnU-`4Ns zZfVKtgll<)uflFIO4rDRO#cazW!B!MI~OLpwJPZ12ECPGm*){H@Dn0x`v4Fgez7g^yR;Fat48{rjjmmgPEvM& zXzFQa&l`}@2w)^%YHY@W4=aPNGttPN(x;o+M&gFFMjl5j#T&}PqTPE)w--OH{vGFO zt>I`}dtnmanW`~5q$iFVErTcYz%6SoWe=xK;f*>CXyYj0cDvM1y*If}p5)4zW%^oP}%)myIYhRL$ z+DFQzc%(0Mm|ws166MdAI!MFW@k$)LO$a6yS+V>5HSc%*VEPB5^q($Z zbvJ{E&FM?_=xV{XFsTOP*UivDlJFL+V`}Z{ogC$nfC}=bV!i}j_(z+% zmkX0b54$7vAM)p?>AQ_fYp2+*5iSMgKxd9a?!WW<_|c#V1M69r%Y=?Jgb;>#CrfE< zS=Vg(+VXru3!k{o*oOilBt7n=B}t@vt69U;z{Xab83CEWw`j&!O@90VAhC5?nyc%N zL|HNytNev|w2D1JKRLFMCdEP!o~#2iJ>)NI3a307ln9Odie+wIDfvMw`FiHX4$2UF z6iCSCStLqn+QW;&=0Kdw?ETA9e`K$|$aZ_m@@50?^obPaKG>}*D%z~1fN2MbO%vmO zp^f>wB*2swW-7}z!W$WJG&#|^mv5|a5iGDs88u_hLRCjvkHSOysUlB?qZx$8DyZ#M zfYuHt-jz^UUkFhn8L?X)kAO~~_~c-PK>T{Z9>}$x13p%`c$(z;TTY_5FWrM_e|A;p zTu!R0`TnIRVf;gdoAQ^G*7sh{pNoU|F@5U@@;uQj$-o*8&QoGzazza$wimJ)I0M8| ziWKRY?Xdmm&hE(QL?2vDQky|vIf}*m9E@FOv0XvQUo6M5aWQ}3l#UZZAAh^!G-hs$$C85v#5Ah^ie3Uk0rHJG_MJB9V05gHnfY2 z5$Emu7ugSkvdN=(!dPwnP=s?dh+8+^GCCgX?QWdYbS)>+u0x2&tLs|<6c4AX{iG#; zVKYF~jvp7th89U;Sm(uYi&`SUkCB$MqtfH^#PQLaHbf08;d!n8<^lukzz;cYCCuc_ z2){z!9Tu|+L>NXmv#I!F@bm{r`bTv2rI;lmY3Y@7 zx~Dtwd3D{W*o5L1`G1nd9z=MhejsNrZRx3p|7f(p$Y~e$`n6xk2GC-2YObN&&!`?6 zF>|Y7IO<%W`BbLojAumBUeXS~6>=HUW_Ot0hsPg=?!#@Xzc#yqVTwNLj3p0vsG7oW zqQu46pq=|HTO^#a42Sg2Cyv~6M^ZURzu1z%(xn~o4yQL}lbZvG6nt?rSCP;=tv#wlSVC1DdI*wc@mF z45RKB{78(#u*r7a;DySBor27k)kzE++kT%~G@ovqdj^Iu0EJlyHYh!=hV0797Y?I!u|(HnFg{vPxgsOqPd;DYmtuCsN9U$#3$$Po6u^ zh$k~67{qlvQAVn8a?K{Rj@MFv@ZPjbg69{uST$NpegpJgk0i0_r0yBf3>f<+-P6oVUXy%4nRp^wZ8lqTg; z$Tr5$H6|?jGK`qCwD-<)frG)}gwZd0AgMcyIwFb#0~Vj0evf#Wb7b}GjVxSKp&Np0*f@~UQ~ z2+sm;pmV?8;kEFy*P4XAutwv@RPOVoQ_xEJF^e~0d*^$;Vm`hk(Pe0pjQP1rGqtd6 z&6=)WF4=H4HpGy_tMl+#5$#m`$^^3o^LbLvGMjDh(-*UbY!0H6vLxFhX3fZ>kW1mg z$l{j9)*r<)KLoj$szH>tqT+xiR`m<`fN*fpODsm|8%PGK}!8^yBLAh z+c&o*%|-R`5d=8WHS@zfsd>>}>7U~J@#{RLQ7aLmZt#17od6(u&kz?9SH`;C=i9!R z@!aJ1%roPIje|W2ZeGY_E#?$S#&lXCD`Fy(aPvFP4tj{!)w1Jq@fkuO>odb<%8wn^ zu!M9=Wd=I=t#4a(s@Vzn%S@TYUL9W|74v@Nq$gw!Cv4&rNUiUd9B6jL3FQMafAj9L z!f0qEm!&wb7zs=IHm^$pel@9uq5P(}9h59horL`wHalwcK)Q%9vbl2_HCFCJ=AqMP zBAXQ2D7hy3t(7;=IloqT;Cj+oey}{2B*)#A3Xy4BzSn9-no1K&6Y{6O7U-^1%}I5C zz}3@U_FHy9McA^SF}sAZ-84~%rIoI|#8);`f`rs$PZFBiK`u)oZI0A})zvHNWMZu- zUBw20K{N%MQas&1x}_<{Vi7S9$r>cL|wk|RhjNMB3qZ1w=+dL@CT3VSD|k z`%Ikd`~sh2`;edp=D94IG{QH;*~kt4#`S@d(#SM^sNp^o=W#}bZR9jgaN7r6j9cl` zefN*%u5o#6vv%~QY@~YlVK5gr+O(P6@kh=5-c3?E$ZnZK{E`%xN#np?4z}m*9Qg&h zyhTvtVPIywpcvgiFp~)4XY}S}Z2E8Sv}FX{SsriAl_CTLh`wH1NH(93MB#H_eqsOO zQ_nqM5+_|e8ig@BYe8*}wUOy3d_SV* zhgpuQ(M8HlNj!MD#*An0IbMjqlNT;(3|*Xat&?7yBst{uFCoVKf~}}WVz4nqwKSJ> z0gRu#hpTj6!=f+3Fdem16)}srzIeu!wQ4pm8I)}ZV@*l>h9-U>=oR&|Ge}8Q5`zp{ z|G=5SZ5tc!ot*JF+y0iGYW5q;ru9->dm)oqM`sDu@>!JoOzuEV9!Qf@Y~8lbGgIeD zg*MSp$NbW5v%aMMX-n;dB8@;$T|8@o9FLXC7|#Fo08K*bKF(51P>(0J2OsLDrDm}VF#Z7^YWUsM+Y|_v1cq9`Mb{n|ULKq^i&1Nub zvRv&f22vNleM#XIYp&2!`g1OOE%R&U{dSFwtt4uHfG>GJS2m0Oo$w0lz#9hDht@dH z?2$UouWA>K&?h$|{7MzcHRSM1LYlr!?!arcd zqB~{cQK&f3@xePaA`e>srl4pyQTi5_>qJph8C2g~D`mXitvIz}|MfEkReo?CK74`9u(xr5bHal&Qvnu@R*f;JfMe7CtMsW}W{{*`b2R z9acx$JA1=oiEEoB-)oorC>#-{!0NMpbm9+1d-}0e12t=OV5{y~0^qDL%jT;r{v&Bj*9ffN2I2kMWjj6QJF342SFDtanXnot#^JEP<9RMW zI%TG<7L?sd=y!ea{#i-gl~gRng&gc`Ikr)g!P_=-u>u{2Sees4z-fKxrQTyjr11N}{inHwwd^q*pGqJBEywUkw9NUwbmu=y1kx#)VH%7>Y)*XARS>z<=X<^9~!J&R;Fl zTx*ze^;C(2Tg(zrk;1$-Rmd!WC@|cMr@)gsdnv!0Uvr-dBSspbd0lg0HX6Tlt)fZT zL8TqbPMh*{zew@hot21|R1Q#B2Oh9rA=Yyu)FSMAOP1@{W~W!m89R0xfber%TVd3& z0CP}Hk>u5z(G?b5w*@0%-Njh7P>-5x47ni!R@KhCPwH$nK{&HP0uQXha7Q9zm2OuR z$wHAQO2Hg1e5uS_p+5q$UAK~%rAnAw40{U=FV?yle4-)5FifAAKvW{jSkj&k=mPbk z<=|o5x$^qOxo6IO9Nz>{NI0b=7&M>fua{j!zPR$om0X8eU|DP~>Qh&1loQ;nhBjPk zok_ns9Vj$;{`U0KB&Wg^-7mrF#oCr~5)sFnh>9fVZf5<86O5gA$esO%>2U8bIJtae z`GU|B6dpb()&+>U0hN?dWVDDIJMkTtT&Jj927hmih(UxE97L70pM=mRP% zYyK?=UoII<2~9n*zge2<$}f*%GBWBfAu6G%EcSBCybSyIl;*xu1>%GaVe3`FHfpRn6emOx`6N)mk@}#@kIX9RqM&1Ug74vK5nWW5Ueifw=dUE8ixTMDvwV{ z5Mu5NqTFs2atqtnV_mPz2){(}eE@BL>)^4*l+5k^XouNU$@>KLvA9_>ZLQx{PLl$+ z|B%q~fb>j$tl7a(8Vc3>b9;DC@}=gp>_MSqeJ}ScSsIKOMrAO%N^ImpIggYuR^TF2wel$dJWRb?2cdC*qU|tt( zWQ2=4Iv>d#W+m5Rm=A%Cb`S$&CfyT%3?jbJGOrdex|caMxalh2&U?)ByP6bey|NJ@ z_Xm8&c$k}z52J4azrjqGk@+ zGGK>t;75mYUVH=LZN%;kbE9(5qVdVL_pt2BtOntiPbz@NNYu4PyHwd91C((OP z&}4ZKAhe)x9}NvyEMY2fS|oAO*Uf}3a#jdp^KKXrGA*f`g_;iad2Q`3G*Z7^f!MuO z;d?_kHeq4B%wVvIfIb<2p+#z(KQUlf6nD8J7)6qLhGn}J75Oy%p?Em?p@3K?ol#;B zxf5lqL}xi5?*R~DV-x5dx+ztG2a7B4O}5w;D9ZCu1(sD4y$0~l$Tztoa<(+K3nMk; z6nTHO1L&XfZCP6TK>YJ!*3J*lM%Rrj@>_#Au@lgcw*^m5jKP)XXw}MwN**??Df^F= zmiRlY@2i(o?PN66T+rT6_p+scWz^3PzBi@Bu)=X;eA(J}u0VfAbxHJ7OFkG5)-PS$DVmvzhSFt)nU|KVrokoSn=gkX?2{PHdWrwEe3;Qons@q1> z#fGDaq5SZlzx_vcb}%8=2i9Q{6Se`j>u=Pma2#RP#1=&uk07E-kI37 zO*+IBERj1Q3x`I#<}<&}LfJyYYq$9HooM>dR>+@xOc1~*+9+g(vcz_e^FlOrJBG%aJPd+3QK-J4?AlSSsqF{gu z$aZ`g`dIq4GT&rmx1|lrQ0^h(c+6Wd+iHrhUtxu`TLKS_d`<^aVK8y|*zh$Fg^YQ` zhD@z~WzTzsk3W<8_1oYvR5xvs?3T<_NBjIuEMw%j(M7w5TNsll=8MRtNI>~-5*s7= zKlC*?04kg@3V;AeqR0y%#}w4NC*HVe|JIv zBt#)Bh9k^?V?+@mM*Evk_z!WA82#TwLqY)a|Mu!dvHO?D|6wVA{{YO9aKw=@A5Mrk z0P(N9{#RcAkLGpadxU?+;9s!+7wrFE!~P4D{)K^m)i(d(+U73|{EPbj=cw;LIU~Z~ zS?K@AQvc2tod`u4kDP>vQC3usm>9W%WOiz0yrG$ek%fsRQ2GUr=qDZ| zm0Q@p7&Ai@YcVr0Xl&L0n{d9ERg&R=Zb*o;qocF4dq{|52#^SIcXoFMQjPOgT$FcY z;b@XzQQWr4M#v%HsZY>9_n+~ZR;(FeyIQ71T8FYmZOsY4u{mmK^IkRSwH_O{xLV6- z>04jPnzrp$i}S)6!Kq@gpBuum^0(G5eJK<=zwJW(;q+-uPlAI&dU&c&KVC7t_Lu>K zqyOr=&Ay#=M-mzzy#L;uMe0f_OnF(d4AWf{+`A615Gi< zg0>hgIrVU2klFXIvE@swo~R!_>UiAmvam^OE@pVbJvJ} z?!5xbSiJiym<-@TfAC(h*EcUKKRsb4A{pH3VxE+pAyiIaRoIVXXmE zWUPc0tBtS!)Kc5M44LBJWR}%?PdKqCa=Pai)Id-C!o)=OJ6&8~f_CW`u)D6{Ayjx`*4n84h_}t28@; za~p1bS*5ygkIc-^tVJcW_g{;0<1OFeZX3Jdj856|4KGr*e=|sxUnU#%CF|q_r*lu3 zo}d1Hdux!am}70n+4Ju#J3kuiy>xMX*rUiT(xSUMZpJKXu-wA;tVa5Or;?S`#K&C1 z1)TN&r(ayX{2@buKoO5xNnmA(z^~i~2CPxC6LJ)y-saRy{oh)3#4AWJm)Gj9&*3Uf zi`55&nsfC2ne;`7Ovzo?<@CL7htEx>70cH!=_O|$4L;1@Ira9>>vcaO%U)RIbTMP?F3CCjWhHd&&NIw2%Q?FX4kG$=YnxD=2vr$`sTcuXDaKAA%+&HqcgT0X=-{o?QXu{HDDAf`NU(E)p0a2Yr@5DTUV!^Q@1L4n6s zOmteO;|dn?`%J_!kmO^~0Y?cx#|gNMqhu){xL40bV|nVLFX*P?0_{QP@l@03=kmz1 z_C|C6(w8QG#Os6glxAf~SnbV9Lec2vF}WRj-s%nKV${NV-iL(NID+bpj>kD9(Exd&7Wc-zn9iN(fDZC3uo^esbzx|s= zLP&apdfFd7DLtjQG!Dcq3rDAzSt4cz+h8UCBNBLy3QQR!Ug4uEu#zgPZ+EJbn)7+5 zC?9+kDW&sby>c;8E-1}USw3qnbLO@}G*d$0;f^LR%d<$9rsT9zs3T!E28e8wh`P^+DtKmtD8CO=rGb2i9g$o;PTw=PAJCssn*(~Z zS*LJ*`k7@eG)Ew38u7?r6q^u{dXQ=B`$CWsmKi>5_uzHaqqZe+$KS%-2QIq;F5IWL zPODbz8FFyv-Gn*m^T2^5^GinR>tJM)b%7K zeJO9wYLBMCQ!KEqJ2LdPF`KsZIolW=Div?qpUSV|pwk-pT>RUSYj>pf<$(r`_13RL#_JG3n`XoSaEAEQKy69F z6M>C9Ghj8%iuIqq{E<~gi>4ovs?rc}!R_G4cc2S?KWq|OB2V=N4h7kF0|0I^#7Hne z5TxNWgbs&;v9VwE* z4<$j%*Jd?)v~R_y>e}zw7!GvPLnfC-JK^^Jq9e@DWe%wL_JGJ_5GmL$+x7<&ZP!Ljm zcqu!azqI%xb*YOg;*3aSHww9srZBvRPT&x3B*EAw)dNf2sMc~5j1zm4)fjBJ{Cruv zZ)a)k+-Z?b_6bD|BPJ$?ug_GJPG7VI!j!&tDqHkh5^;$aY6i%6aA*~r zR7&C+o>iha~ow(q~SW?54}u47#yq?gfW#79>N2T-DP{t>YB;9s3fM5v!Jlpr?K8MKYEm zC}Itd-=)+V3MHSppV>qOFw-n6y6#8CC*SPweY8Cwp_M)omAhWJRHQiw1!zS=ha`)b zD$^@AauH-)BfsdvHDB|GqkY2cJDX!|3wj}S0Fj~Ds|`7Ks^)F*8we``>VlMA&%oz| zN!Th_d{2(7bvbW4G-SJpYS6;mS`U9Yi-Wfq$3iJuAP7Y7@joaWHa7al_qW!O3@mA?s;|j=@VQP@<%}woLk{^ux=v~ zIXk775Yw<~+lMyM9`JcPreh`I8_QONp@MFRq&?(g(kTj~#riSFm$*M?Y~Ht;k5=7_ z5t+IPyY1?wp18@~RIk5{-VRLM$O~jL+sn38|B(8FC20lPXrG-j~8(v4PmnKg>sb0MdRdF{Oz_gEP0h3LfGfjz8CQT0i_j)ky@{f4BGi3mG{AhT9+#GgbyDcJv z@Fhyn6JuhtG1GguH(j>(i)S80#7SKzL%V=lr72o+dl>7ip6X0pKbT1URB?^C=rk;4 zOep6#-fO=8rPHJUZzc*a9Vgr&;V?l5EN6}{R}P;1zTulypU$q4Hfhm{A98u4q%@Vn zNFa;Fc{cvKiDg!$WVva_dPdt=mXLjoLN_lauC#Tp`P3R`;^074E53?dbYr zmNyzMhp{|8R*xUmF{gx>E1jLHUvh-X9F?2nRAJxoZ`E-rJlz z{78_rF#u^3uh(Ct)t>+Kr)R@?Pn2a^qQPV&kI8Taf1||gZQ=v1+h!Og^#lDP=^1*Y zdGw*uq*B;|nRXMO@?d1Pu!K55DZ5KPqcx!i#ow}E8L&Bp($Z`iTelr4t2+&zw47;C zm2fm1qnx^e(r(ab#Lg)FG7!U1wGdHdP*`E`;*;NlD$zX(<4BS?W6ZqGMz^ji>B-W{#)FOxX6lQaGy8FAa}l!_JtO)LeE4$0HJWR5o7nqF4pAVY zX5zZ?6~;`%*S9$(x@E~N$W{HrC*+lEr7w5!tWo%}c+UK6^c0lW^!l{72>Xm_3o4^5eq`$$_5kLp^U?ufTmWHHkSr;y_k z?-_L~>?C;1PUcHz8GpibSjA@g(Xxc1G}cI`_0HC+vt~h=wh9bsSys_dCi! z-&P|oFBwN0PG-4Em&89I4&SlUxJPqG?Dj1Udt~0QJO?|@j8FAZzIn(^7HKrR|N4l@ za!^lzI*Sf=jb1!ttSi_^gIc})0%5JPe_hJA{_}kc_gDj7BM4%&Kt+u1T}nz0^22Ii zvDDhOoKb8d=uq&HYcGu-lU#gHajz~dd#7BV;32vI<`k95jZ!S|Bm?9r-K<2 zP!QN=a?Q=WSCb(e>EX2&KWS{3HbVuXdg((Kd-RP$iTg3J^ZHd@&raT#VgcnmMRmvQd+K9<}6c(jFhNMs*jCDY~Jh=S2W_FdB@jaQZQ&RdGAFe{{z$>!V zAfs6z_`L3XraIx>Oz{x&nAmO8&&Z^`@wZs2qZlf;7mbs znzR9CnYhGW5f&RagX9OZmf6312)B)z3Zz5E=yhXNKMB54cNp+zREo*@!P<$_`P1Y5 z>mH)Ku&s$wU82ysP&FCOUm{V%W&N!`R&$#S+U2&zEKo8G+7Z~hnFw*LM3>$5B%TZH zKyBA>KLh3V7O~Y;+cZIDA=n}pt^yL%JyAdS;D@Gr(XYkQ_gT5BZnn~NB9IbyLj{Ly zPo}frCoj>^h@@oACNMztJUaw+NI?4ue+bu@0Jj_}IL!}ZWPTR(Ftm^dcE@;E}Yhs-SQt2APi zj`znWcO$TmfXZimip6W3W3-_G`Y3q;MNOHDq1}ZWdejhd2(uAw`$AyPtN zEC<7^M24t5f!m2x=`fcuNcL?Jqx$!V>eUej^q&-|K}-2Qz$?j55B0eq@17D_?!=;s z37Q@?wIyS{!_wZWViYYjYWqDoso3v8-jh?l=GBqfZqgwL8H{n0Ym>z_CsuzZx{-!* zH%5C$D?}GzEB;-Aj=w6fn*Ww<_Cs2_HKPEbUe zVUNemTbyPjV6Foz(0VP{E2ZUeI>#RPm5;~OVlT^u<_dyx>f4nU_&!< z@V5Hxw&Cmem;L?tWbtc1FU4HLl~KQk7(t#b`jNan<|Ezju}nrV!mfOfmvPw}+M!w> zrhUy!c5)M+Y=v&zl9IXploHCV0_;(4&UJS}b)*Rklo}C*He-}`a0=86hz9vqrsRe>kjh-#S3LgN%zL7i#=b$nuK5^&q_l$O~oQHFV=`U_cl{o zx)TMFF(8(KiIG5l5vmVeV6-vfbg&oJA3LPg@6hs}48eW~ThBDLqt94vn)^@08@zQ= z-&3mW>3nHstS7Q`k5r}b3j$lG>1`^%t7*7KaW^mebz6vh0F~lePM?Kw5nVnZ%8}TJ zW+Y8#8t#~gWyZ#O;0OzHiBne^t_|(qCoh|w9b}(6F$TxT;S}+)JHM*n_jq!|`(E_q zS8B}H=jIG_1aY-9b{LgU7dV|eisTJ^IdO!;C!_sVKl4e-X%kqD_SA~_3Iki0oav@< z1C^daz;C=D8;8^vYAQbi_PQ=HNYjFx`j2HFknZ6?l6u$jdY%o84=-mIScBU*>Lr(` zIyKDkHC`c570wA^9SI~&xs!O?q6M_vBTK77tEZ z81Y;3SAA54R0O_j@*ZFHj?-3AV2$z^(X&>XgJz zVFH9>1bT0tU$!ehCbWc~2@e!wjEgSg{D~;1D}!ZY3rir{n&9L98Th+|j^~l6u6&^K zjiT;=O>pyD0$@h3yZdPx*{|B|-(jnx!5(H1+7v;gTzI1vIE+l8B0ZYk=T@CytB?6n zXBsd0I=V(~4edpA%S@$CWtu?BmAp4@e}Yx3Q-#k#-I&m@3QzY^K}D(wa0Q)>IeimS zpSLha%BpKdD;`{zVlf5P;%TG;%HGl`wtJ(v+L1rbq-9QvyjgWcVBfcAUOHJQ6d0YD z{pq0N`Ak_eNVcpxQLkUcc^$y-;k3Dm&8@%PV*SdgFmLDnyU}x zDa!n^du_;d+#9(wP~SzJZFY=5B@~_pd4f*{RXtP7+0E#vCP`|ma`HVJcox^4M$26e ztC(3w1wpW4!-{yHG%n2K+C)DsxAL?uO#u6YQ^Rm}Yq|tu{J3J%)@DlJjrE>X@N< zd8@6kLY1IBV^7i?g|^(nO%;ktqlla*k_CZnL14V_@YgEgXfODi<`}5Z$*3}jsQ5v6 z&!VVt0qRs>E?s=V1276_#uLnEKFb{XHhl4I*WfZMp428GE%$`=p%v-;7v78!{u3%Xio;MG(jqhudvza6){#}N^+-XoV)Qd%C@dYS3fEV=<-wz z>IF7&wL1@>VhL8Vc-t&pGTD^F#W52D1bF>OGO;rS<%g;|eyhVm@9#^M=-V0X$C>8^ zX=xhEzjNr-JG-hDH_nDX)c>lTR^+Aa3khVv52+ruEMBO3Ov)-&h(5sE`naaQQUf6x zEBxEj>KxBN^^=0Zl|PdDXHEr=w4gsIVPR4!w}Vf6m00&F!Bb)B<+Doaw;dAvyI^-u zp`tHM*Fv6;se)Dz%ZHDP+8MsbVC|7$@6k%Vv@8@%R5E=dM=GM$!+f3B%G;T*K(P^FkTie}MJjUj zb&x+cK~#E-bShB93s2xzv-WQqkKm9Tc7pE>0(MDe^pl5)*;v^bRXnQX=1LBe6Rt1 z;+1%Fxaow!b0n}s!>kbT-AGoOjm^RKdkc zjJuq|7)tYBQVMS3e?kf%1`rsG1%QIc)r0_KxRzcP4wmMo9u~G%PG)!E2o#4IM22>k ziZBEIsULbdn>pIqI9pkoI(u1|I+@uy1EA=4i*Q`c+&%3)?OdEq?JSv@03;A{Dsl-H z02LI6910-+y9pFT0wL)GlDq=4U`dcc{t8?ENm$4p{2jdf9j*wH0NDO-kM5A00000 diff --git a/lapis-e2e/testData/temp/unaligned_nuc_main/partition_id=3/data_0.parquet b/lapis-e2e/testData/temp/unaligned_nuc_main/partition_id=3/data_0.parquet deleted file mode 100644 index b953fd615673f6d4d77db5e42e354e21c540275d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 44746 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�s*T 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 V?AWq^2qY^FA}0lb)TK0e{{urwQN;iN diff --git a/lapis-e2e/testData/temp/unaligned_nuc_main/partition_id=4/data_0.parquet b/lapis-e2e/testData/temp/unaligned_nuc_main/partition_id=4/data_0.parquet deleted file mode 100644 index 764b458d9e2af1d8460b022d96f0cce38a9a34e1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10414 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≦i7{o9xiRP0U#wNGq{ zkke81&q9>$_)p6m@L;CthQ<(2tHl&8)F(U%jNZqy!9#9ZE1xPV0ZD^Syv;$j=Pf3=KRyp zGKfy~HMSK+G&{b)BD`M9^QN7)@_zJ=_Mo?Zm5KGErLvEmE0u9L;f0zrefgIoLG684 zF+gq#48q+4!4PiTi~|}2IgV9-EY$+5BY&b(pN{dKLk$_7RBK^Fw0{9b2_?WB#EEJs zxPP z+_LcakY)e)zRn0q3Q|Z;iUsVOio6MrNkV>8z!Gai9_-`uw@MutRibFI*s^tYeNGE zpz!D2{vHOFLUC^-nMm!!=W~Ye6-#m~%!ed1P45*sMb1u1%7%+FNBh>Sd>&BE>z?SJ zo=pjgK*Y~07?xgT8+aDeBqbjY1T}hoSc)AN*-Kd6;L&&s4U3Ryf@R&u09=`DQA1)v z+Jw3&Z&zNw(md^kviA0AqJ4_(R14s_n(U7f)qdQ{2@VV`rF>h>O1B z#-N^XTh@2c(GO1`@fI1jEMEXhuLC2?C(W7VAcl%zSnvJ!@y2xGUfyNLSU=c%Sa46R zYPX`UW*a@nqraW!+ZR}u9?7_kW0vMZPH#U~5qLmS9}US{q^NO7D8J*8Rc$+myfFn?j78ngn_zs8xxs zx)6S>njZ|mGU@cC2A&+8ij5CcyfrQ)LX)J-F%>_JU0*9Lu0-dZ!C+nTkuLXL+$?Z> z9)9Ift=CTpyOx)jF&1g?wX~S96gux36ue7nHT&`&oS>D{sRu1^aXJ}aSA*1a`|F8H z4sB@->__V(@#y{B=UiTb=Y=y=7MOlCvF$Px)Y+`gcaxo?0+iEso2Oa;jv6iimGT`g z7}1_RN|n&$B;Qx5X3x^AzD=UhR3MJBn2594Hm1f-m@%%97QAyyDbIx+dY~m+#1Z4V zP*q}M{H%*6OY!1)Aw|0@lT`x8egQYztur1T2ZHm=`bw<2vJbsz=cQhk_^pW3)8#yR zFKgjI6#`@aR-X4UJ|`3-zCKv)VGp-%8eW{I`;cRkoXTzD9S@QiIrwx{$BsZLRxX(m zrf=9M{!!Ww$N;^+R0@iWe-ZGneTm=g_gec!$G^{@*4KZxAno#cTIbMEa^V$3#~D9t)_|QIsUo&wpT4cuc;?(Ehw4a_+P9^oB?5WnB+9%t)banp7-n8Oi0a8nPvd|RrxFxXWy`kLZJ&eTib z!@ZNyP7H66HxNacLnlD*K(}V@yRG-}3#}ORy6$VD4NnH0lnKV3VfUyo-BuE9dB8Z8 z%8t};o%$*>6C|_a{j~PWP2DdoPOde3m%*xwg=w7*2LWyk{3xO?i_0^2miE zb*=4BNqEr+zpJL^IlWUh969Ny0;BWS?#5Qf56q5adccei0!Q|`d0dz8Az}M>)11hj zlg`~q@4)Qt(MT_LWL(|hNWP#VpcnOi1Vj}&e4#Y|R_2hPLZvyXm;wf10pCCXP!NTR z0Dv6N+}+I9+|R1;Zf0a}V(kEc zf>Af&I+?h*S-V*~Iv81-Gcf|l@F}P$#F+t9P+STqfa3Qi?{%$tTeN#)&_K|A+AZe-J*3ME|hgpB<$?J4%0cl>Uz$r9bTV$L{`rv%7!$ zMDTCt`9GZLZ-LxOjrDcWySTST!9$DrgfS&*W K&_MlD@xK6}$QFSB diff --git a/lapis-e2e/testData/temp/unaligned_nuc_main/partition_id=5/data_0.parquet b/lapis-e2e/testData/temp/unaligned_nuc_main/partition_id=5/data_0.parquet deleted file mode 100644 index f698c18d9ef85a89b825e3463afcac420d90bebe..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8290 zcmeI2cTiL9w*Pk;1VSgF_uhLiQbJb{kS0A80VyI)LmSq@uK>gtR0z1%te_yu73=f?S9}QbIyn zLRyZR6{(=8C@&`^Mgag)Qo;aSR#K5wiA+*aN`jSAPg+`D8u9mOzkeYkB}>Q_gF)3g z{I|sY67K&<975PC&?NrLane5;0>l`Zq0P+9U@*L^t{Ga_%#0mSgjvrdL~-R;Gn9Uy z4HqX5zx)7JLr@6qQYQw_; zy&f#WyPMN^_$9eL0<^OMYV)IsnGg-`Muh-Ip#Y!(ih}Fvnt?*`_JWz39N8&&^^gJe zflcrmTgW>S)XBJ7DKti2V>CI^;CAFTl;UvwSVO!DdeK81`WSoyBPqS1H=Dp^REtG% z0$>gpu~;Jrr_LEK7c2^`%pu+!)#s3FUIAHV0|4qA2?b=pqG;GDpdko|5bo8~&`|d( z;YLMKAiOs}hjHY(d%0xAAywlX>P8(u-gW4b=%RtNyrt|LFHwnJDZ0zay&$vXgueL7 zny7=*`ICy#j)Sq8%M=GmsF230noE%try)+nXtCD-OA?Nxw0#M}>D|et5Xp}P$7vI7 z4n{AiZ;3h1qmsb@buNc25-24+at#g8bHEIg2PHfO$YBK742v$EW;cOCIS1AC1YOx^ z)We&+_)5+%3ln;`B{57MRaBG4LUa#Ch%B>!DkctF6To{K5H(m4SYIi%i?-mTZ5&XV zGH_FfhD~Y0dxc1kO=befCF_g1jSK8IsT}T}lR(*n2XR;17o3=DYbxhJ;h5oI|B=qv z2rY#Mld#-o4<;82zVF%MvC&5AKzvlq(iCryT$ed1{}+0u8Xf-vMYEq$VuxQ=q?IxS zMVNJ^6UjQ+4`9!(=WS5L91sg|6}DbefpD>BF-=<)_lZrW3-sJ0QC@C=Z5%S*rNq%cwv5j^IOT- zI$e17u8_L4MMcYPe4oo_<;&&kE3T}+iddfP$cb17?##~HV=^@96LczWXWqZ?&-d6@ zOIvx=2T5S-y|vPtKC(A0k$o~xv#h!A7FMvTia)AVTbHur%?GFcs|#pD0VF{o7=BC* z6`>iR(Ha?;=0I_%D36i^1aEF|?$oYic|k_=uwea7ztCa<&7knyD~6#HQ>IIripm^= zlZ%@2#h_| z&FUv316Wq9fwTSFP`vtb{$(fRq`x2F1Y-fbSS=*?D4^NMfP;yMtUf9cX`ma`k3^%Bh-yT;FR zz8Xs@K5g*d6>4Ukm* z$u*t1$l<$z=p7AEY8zF6L2!*~seU_P46rW$K*)0UmdS%-lZvao8$6`r1^0a4=I^Hq7~bR8 zTx*=`hZN0bn9iRN&KVRLzEOC3a(BA*@d;5mokb^=Fr<_n~^JRFAYM55{p# zD4vS=q8u-u^G7WAk;p~U44t*mpsWU%@%0YU^yfjanqDy zv-Ei1X#lgSg9YpYJkG9#$X=$S*(BFWfWYUUYo7Y?pXpF1kD-;)BzBdZd%k7f+Mtv~ z#&WS870jpN`~w1dyhz#0M;NlgK*Hc_4yEm&#!{}pYg|lBjYnk3%u*j^0RExRg;hzD z&84l<_niHM5>g;R55GU}5hcl0ii2bdsg9u+42y(2u6NZUruIeiy<9n;f1T$vt?Mw4 zmNcX-&|Y9Ux811hG!ZP}ZgX!PuYqOWp~zHA`9Z7IYQxcgSW;jT(^aP-AtLnYfpz_) z^eSKY6vnE4k2!dj?3njazVsa!(xhRJa;xh2O|JD`Frm@y9a}T-RYTdJcx1q0RAvLMkbU&=ZsNQapm2)NMIC$y_h*++?Lz2zgdY z`rLgbCW`;Dd-;=R4Y!d3e*G=CwM#WEE=i{J^GgNCdyOlAgU?OIt%4^*Oyj=YB1PgS z0Q32fp9HAlJJH3!agAa=UAqZGKQS2nYe#`(`AQt~*bm1+LA(=;6|ddlZf~3;Nu;dI zfJ{stRG!ulMS~Zy<+B&}jvmX;zQ}&}&1Q@3ac6z+nQLC~AHp-l`$tdd&A$&1F^?9| z6`u)JpQV(GRP#GpMsA+U(<;WdF*K&HCPxLzIJWRL)%?6_??k=M73b(d&d8^#C z6XY4=Oj(GD)byU)zP!-Z-GBAa`D?GFcn2 zRhO1W0Z2VZ+PkuQ0#1OGZNgaOtDvlH5h|Wj#veu*`XXj0y50fx$oOeC>&E@!cuU86 zgFGS}-WZbCz8fi7e9ku^*FFjrbM`NF=X?UT~uWB!XD zA4dF6>ElBF)QHX&9-Xa9@$U=&5x%XG9^odI&>o>cS`>T5Wf}OTO>N zv^gj~Q&HKFdm64=g$&`sAv1=e&s0V1_$sqnJ_XkF1*Qn9|aweVb51-N| zKiPk2KHD5xpxIy^CyOu)p@R0itY{|21hkMVLb~0hKR6QcdXmU@-rIdbezv`y1`$uX zbqQc>iE!j&QH|z%i8*9J=uD!IQDzDv47V1hHkNm6}53Vv* ztuD)vJ20%Y)z_a`oFd=+y1KP*;ln6H{FP&OljEABiBGomteUd=ozMy~^7*Ct<06Hq z^t)w`g{R3h)=k!shP>atun~J&d=lHuJUt2AyW;f0`)A*5MftN!{?o#XiA8GW&!U>m zEbj%x%C}3!XezBbGK+_H)<2F@zd$H4iwTAA48Q65l{o6_r7>cd3MfGgIZ&_PtWMp4 zn7QjGEMN))9xvojn3=8AzX0jvtLW|MJzXE%Mh{AsMSRR+ry_BBIx7_thNM~L(vbx7 zkq@?yx)7tiI4l^u*n)5>a@>-RA)~L8@ZbA5bTS#c>XR`E*#V&qE_|QX((23KJk*ge^-yegZPs`?e366eXRITP(hDp)oX5OR5r6g z&M3?BrG+R|Pgy#7e0xQOewQqr-5pila!sIG0oM;!KY(n^A$zg!!N2HVPIn#5Cxfn5x71v8w543%WN+4enfvQ*Bpon7gqf zljNW}<&WERSc;%t+(nbN&8FBV8tPV6~E5c)x zU-ffd+{dT}r-jWu+W~QcmL7`9Ck_J-i}RbLZIh7_T5n0nNY4u{_`b$Ji`0wu$K+V- z@9BEuCkIu!cXg=eSZS>4wXoCg{@5>AlcYF^qi(yw5_U9EjP_Wx8CQQV{1(XPts+l& z6B_k+Kg{-6;p>VC*B|2#W0&!)XyAJhImcOem{*1msKW?$(nM0Oj|Jz4-3X6vvo3(UKKIVFVFK^IHPlZAs3ATW-Op zk)KHs`xNiFAQp^vVYu$Q9kZwO&-_>I?p?DGj`i8Tn>BxowaFWi8YWv?R4o0d5m)=x zePiC`b)$02{nq1mYH*IE~-+L`euxsoN1f$ntL~pOP$ESv{4PJ4pOhCrNs5n zVM15PR9aRa2*#HP-5%jSmbcJp?^rrw+5rthCW@9)gFn|v-n>U`@*0sJbeo!XA-c}< z&0#OMt%00oSq77W zE<%@zIy|^=mYslASSa9M>?3rd;5NlSIVSCav1Gp%q3|rxBp7d%BC7j=$Gl07fvj_* zxeQnH!Ta_Wya)JHf&@&#_Hifen|HXFfDOlf(H+k`L^o9{E|Hy~NTf z@r!ZrG=9`{8hx;Un_GXN57aG1D1V{&;u%41$zh!n7Z}LObL$>su+YB!tMQU$txwYd zBf_8mBz?i?+1vh_^VaHow-_z=YmpeG(Q;p!Cr?A6O`Q$ivk%>lf(3RePML3dcF@uc zpTX*Yku8SzPDx+A?hvVfYpm;9%Y`-&`XjHLqB@te3+Y@c&AC&p6K$PT#9(!oDV0gr zP>y6$REu_5){nu8m_iDwBXt|7ND%NJ2G)Vl*`V zD(A1Ve%JHQVnnf8ze!#cR1$6wTXdgB-EqPzJuE%tKrOWqR1sjV&a5m%gi!@G(g?Ya ziA7z7utc-;HdRc`Z?72RR_1nAj5#W;u+;=*h3Kw<9)6Vliaxve zE?>N8_ggD(9F}u7BrUV%Cia@byV6H&3kge77`_{Sh%A`$TZQY)Sl(`-xi5Dibd>iU zQDrG@+s#t_h@JkV@8sI#pXYspO<6+dP2$e+@h|y*Voff9h*BBB22c*Yv0<|2mEEfE zTtg^w!$^QE(0ob~@3?JdVu=SEK3JBPxU7)5DFUx-TD;qst!em6N2exZg;Bu4#0JA8fm(Bh=C6 z@2#b405B5u6|{K-Hhw;FTr3f(@BxH}f5$UlCOQ$Px< z8zpkjskWxu9y8jIP-pGDRc<(Degn4^Q-XM^IQC6O#QH-Oo7uvkj3&;$icEj_R7}F* z)aa)0dk_^e(&{8f)h-LSl@S-(nCn(_TvUvBF~LhZzIxC2%bWtg!PapspN}L-=E;w{ zS@yz-;FZW*NsgK~1K`kA8>}-dlr`lmX_XYS-LFetRj2EwT9KRA)ci5zuwfyQ)!~hP zwY3#As7};eb?!&n7@kgD)|KF}$7U?D7o0a+RWJ93)?Lw;rb%l|YT{;N%YpSSp*3bTDQ#>cJu7Zr2?W*8;uoVGC!fXKX>eJa1Bh(YB`p zPgJ@XH`U1rsJ{|~;`(o---6{IpdSX1fG*$wH5>(Iye11Ukh=srd%8F|_&dA1dSeK~ z2oxDFm;pi@@BvUz!UZy4j9-99fX5vl2M-rs z9)J$X$ik??2e6>X7*PP@Ux%Q;bV#~6Fx>%&53a&M`g^wVkC6rg;&)7#O#Gf#&;bJf z+a-eH|8?U3P|9Bksxfr)4t!@I6^1t0Kc^V~V0nK_lAub$`pxuyH;LbEL*u`+`5(0R zAGG&xf%X{UK!5*v{|(HIAj$t|=|7nK|0*W`x6;zz9tQo(75_ii{L8(jKy*5MQy3Kn qIE=9K_xe{vkm3LEEny2C!EX8BfB=ye!N0XMfk|QjFebcR@c#f}vSC*M diff --git a/lapis-e2e/testData/temp/unaligned_nuc_main/partition_id=6/data_0.parquet b/lapis-e2e/testData/temp/unaligned_nuc_main/partition_id=6/data_0.parquet deleted file mode 100644 index 448dffc21a59faad0aedca30168fb32f3f3c4c38..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8820 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 diff --git a/lapis-e2e/testData/temp/unaligned_nuc_main/partition_id=7/data_0.parquet b/lapis-e2e/testData/temp/unaligned_nuc_main/partition_id=7/data_0.parquet deleted file mode 100644 index 3724188b6f7f2e987dcaad2a0f8443c993dd5a6b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3944 zcmeH~{XbOO9>@2dC!;YK+0#ta9r9F~iDneVxif|{9Mgn$m>kAvJVhR2QZJ%Bj>k+z z3Nev{5OU7#REFfF=RqZvGo^%jX-+qC>r{8AUiWlguXF!^+pF&n>-GKawf1-Ky}s+S z-fMeuylo)>$^fCLzg7|{ z9)H8$L+QWNJ61N_sE*vOY$&Q-a-piGs1N-iAw;oSH}c}x%J-FhD!!55h%n{&X4QqMXNuyj zWeMZA8l+jvAD0-GcfR><-N~x-rFG1nOwse49Zr1V#Ld?wPlWx2-nTCHjrk0+w5F7m z($Vj{atj5L(Z%!Q``+#f3~ZL;uxza-#`^PrIIuX5R9m(OjV+Y=w7Q?3j2f?hckl_x z++7}SaLkRlq_HwB6k1N~8|z6OWf!DL%HU!}Y-i`yFtCQ{iIwzrKqBI_MwsK2I-)n# z$`x&BDr_(+f$g3R^q%XjAD~lmqBr{D#$vP%lV6099hDkTq!+=A7Zk&Gry{|RO4#0j=(8TL0e;JfOo38n`oagPgva*Ne_Bp&-RT%o$}X|TVDqNuL^y0 z9574g6nY)R2zc6k7?@51UuB~0X-br~nLf$%s8&M)F4il6SWFa)X#e`nDdhJL*ox~# zmj{o{&~oWst$}|SDO#N#Ub#A&UsA%hlo=oEajSRa%Y!;Gh0DJ^R+}H zYA1erwv=7^yvs1=q(W+4-w{MypH+2?3`kJOg!5oz!jT$$G#;WZ4os)h zks=^fKpez)ygke6T`f+`3_sl*rgP z>V0`^H%jZcQIG7=j5x3Vr~Ts#PVge210NXYRC()1cAwkQ)^fq832r)g=8SU6&E+?D z)2tIeKer!Y>7GX&W~`ITLzC^HFYtitV^^f>gZL>QGELao&%! zgO2+fPIp;Ndy$Gwzvn(}&(d;(bE+&uUSs^r-V9yIxMs&lqd88OG#KCHp93B_|4rdf z$$!6oNkZ0kS#lx@KP)~*_ZWcuuW(!12dI@>oPK(k8RA#gE$<$#>hLzi}_^&S{+e0*)oJ!KlQDCg|F3hv9F3#NYzyT=M+#mG8Tiru^bocG#Z_bo896^#-~lU~ S3vwWFaR#dJ0N{!IWB(gj3SwCR diff --git a/lapis-e2e/testData/temp/unaligned_nuc_main/partition_id=8/data_0.parquet b/lapis-e2e/testData/temp/unaligned_nuc_main/partition_id=8/data_0.parquet deleted file mode 100644 index cdebbd3eb4f9ab3f5dbedec4aee45ee60e31064d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7647 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 CWt+DE diff --git a/lapis-e2e/testData/temp/unaligned_nuc_main/partition_id=9/data_0.parquet b/lapis-e2e/testData/temp/unaligned_nuc_main/partition_id=9/data_0.parquet deleted file mode 100644 index 8d49e8078178afcae70a13e2a1124e4b83e338d9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7728 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 + if (segmented_ == "true") { + return "lapis-openapi-multi-segmented.json" + } else { + return opennessLevel_ == "open" ? "lapis-openapi-single-segmented.json" : "lapis-openapi-single-segmented-protected.json" + } + } + + def getCustomLapisConfig = { opennessLevel_, segmented_ -> + if (segmented_ == "true") { + return "../lapis-e2e/testData/multiSegmented/testDatabaseConfig.yaml" + } else { + return opennessLevel_ == "open" ? "../lapis-e2e/testData/singleSegmented/testDatabaseConfig.yaml" : "../lapis-e2e/testData/singleSegmented/protectedTestDatabaseConfig.yaml" + } + } + + def getReferenceGenomeFilename = { segmented_ -> + if (segmented_ == "true") { + return "../lapis-e2e/testData/multiSegmented/reference_genomes.json" + } else { + return "../lapis-e2e/testData/singleSegmented/reference_genomes.json" + } + } - def customOutputFileName = opennessLevel == "open" ? "lapis-openapi.json" : "lapis-openapi-protected.json" - def customLapisConfig = opennessLevel == "open" ? "../lapis-e2e/testData/testDatabaseConfig.yaml" : "../lapis-e2e/testData/protectedTestDatabaseConfig.yaml" + def customOutputFileName = getCustomOutputFileName(opennessLevel, segmented) + def customLapisConfig = getCustomLapisConfig(opennessLevel, segmented) + def referenceGenomeFilename = getReferenceGenomeFilename(segmented) outputFileName.set(customOutputFileName) apiDocsUrl.set("http://localhost:8080/api-docs") @@ -91,7 +117,7 @@ openApi { args.set([ "--silo.url=does.not.matter.here", "--lapis.databaseConfig.path=$customLapisConfig", - "--referenceGenomeFilename=../lapis-e2e/testData/reference_genomes.json", + "--referenceGenomeFilename=$referenceGenomeFilename", "--lapis.accessKeys.path=./src/test/resources/config/testAccessKeys.yaml" ]) } diff --git a/lapis/docker-compose.yml b/lapis/docker-compose.yml index 22c921010..37616ba47 100644 --- a/lapis/docker-compose.yml +++ b/lapis/docker-compose.yml @@ -7,11 +7,11 @@ services: command: --silo.url=http://silo:8081 volumes: - type: bind - source: ../lapis-e2e/testData/testDatabaseConfig.yaml + source: ../lapis-e2e/testData/singleSegmented/testDatabaseConfig.yaml target: /workspace/database_config.yaml read_only: true - type: bind - source: ../lapis-e2e/testData/reference_genomes.json + source: ../lapis-e2e/testData/singleSegmented/reference_genomes.json target: /workspace/reference_genomes.json read_only: true @@ -21,7 +21,7 @@ services: - "8091:8081" command: --api volumes: - - ../lapis-e2e/testData/output:/data + - ../lapis-e2e/testData/singleSegmented/output:/data depends_on: siloPreprocessing: condition: service_completed_successfully @@ -30,10 +30,45 @@ services: image: ghcr.io/genspectrum/lapis-silo:${SILO_TAG} command: --preprocessing volumes: - - ../lapis-e2e/testData:/preprocessing/input - - ../lapis-e2e/testData/output:/preprocessing/output - - ../lapis-e2e/testData/preprocessingConfig.yaml:/app/preprocessing_config.yaml - - ../lapis-e2e/testData/testDatabaseConfig.yaml:/app/database_config.yaml + - ../lapis-e2e/testData/singleSegmented:/preprocessing/input + - ../lapis-e2e/testData/singleSegmented/output:/preprocessing/output + - ../lapis-e2e/testData/singleSegmented/preprocessingConfig.yaml:/app/preprocessing_config.yaml + - ../lapis-e2e/testData/singleSegmented/testDatabaseConfig.yaml:/app/database_config.yaml + + siloMultisegmented: + image: ghcr.io/genspectrum/lapis-silo:${SILO_TAG} + ports: + - "8093:8081" + command: --api + volumes: + - ../lapis-e2e/testData/multiSegmented/output:/data + depends_on: + siloPreprocessingMultisegmented: + condition: service_completed_successfully + + siloPreprocessingMultisegmented: + image: ghcr.io/genspectrum/lapis-silo:${SILO_TAG} + command: --preprocessing + volumes: + - ../lapis-e2e/testData/multiSegmented:/preprocessing/input + - ../lapis-e2e/testData/multiSegmented/output:/preprocessing/output + - ../lapis-e2e/testData/multiSegmented/preprocessingConfig.yaml:/app/preprocessing_config.yaml + - ../lapis-e2e/testData/multiSegmented/testDatabaseConfig.yaml:/app/database_config.yaml + + lapisMultiSegmented: + image: ghcr.io/genspectrum/lapis:${LAPIS_TAG} + ports: + - "8094:8080" + command: --silo.url=http://siloMultisegmented:8081 + volumes: + - type: bind + source: ../lapis-e2e/testData/multiSegmented/testDatabaseConfig.yaml + target: /workspace/database_config.yaml + read_only: true + - type: bind + source: ../lapis-e2e/testData/multiSegmented/reference_genomes.json + target: /workspace/reference_genomes.json + read_only: true lapisProtected: image: ghcr.io/genspectrum/lapis:${LAPIS_TAG} @@ -42,11 +77,11 @@ services: command: --silo.url=http://silo:8081 --lapis.accessKeys.path=/workspace/access_keys.yaml volumes: - type: bind - source: ../lapis-e2e/testData/protectedTestDatabaseConfig.yaml + source: ../lapis-e2e/testData/singleSegmented/protectedTestDatabaseConfig.yaml target: /workspace/database_config.yaml read_only: true - type: bind - source: ../lapis-e2e/testData/reference_genomes.json + source: ../lapis-e2e/testData/singleSegmented/reference_genomes.json target: /workspace/reference_genomes.json read_only: true - type: bind diff --git a/lapis/src/main/kotlin/org/genspectrum/lapis/model/SiloFilterExpressionMapper.kt b/lapis/src/main/kotlin/org/genspectrum/lapis/model/SiloFilterExpressionMapper.kt index 5a6a70bbb..6cccb1e5f 100644 --- a/lapis/src/main/kotlin/org/genspectrum/lapis/model/SiloFilterExpressionMapper.kt +++ b/lapis/src/main/kotlin/org/genspectrum/lapis/model/SiloFilterExpressionMapper.kt @@ -409,7 +409,11 @@ class SiloFilterExpressionMapper( } private fun toNucleotideInsertionFilter(nucleotideInsertion: NucleotideInsertion): NucleotideInsertionContains { - return NucleotideInsertionContains(nucleotideInsertion.position, nucleotideInsertion.insertions) + return NucleotideInsertionContains( + nucleotideInsertion.position, + nucleotideInsertion.insertions, + nucleotideInsertion.segment, + ) } private fun toAminoAcidInsertionFilter(aminoAcidInsertion: AminoAcidInsertion): AminoAcidInsertionContains { diff --git a/lapis/src/main/kotlin/org/genspectrum/lapis/model/VariantQueryCustomListener.kt b/lapis/src/main/kotlin/org/genspectrum/lapis/model/VariantQueryCustomListener.kt index 547dd18e5..b644cf0d2 100644 --- a/lapis/src/main/kotlin/org/genspectrum/lapis/model/VariantQueryCustomListener.kt +++ b/lapis/src/main/kotlin/org/genspectrum/lapis/model/VariantQueryCustomListener.kt @@ -131,6 +131,7 @@ class VariantQueryCustomListener(val referenceGenomeSchema: ReferenceGenomeSchem NucleotideInsertionContains( ctx.position().text.toInt(), value.uppercase(), + null, ), ) } diff --git a/lapis/src/main/kotlin/org/genspectrum/lapis/silo/SiloQuery.kt b/lapis/src/main/kotlin/org/genspectrum/lapis/silo/SiloQuery.kt index 76d4edf9a..d6f2a775a 100644 --- a/lapis/src/main/kotlin/org/genspectrum/lapis/silo/SiloQuery.kt +++ b/lapis/src/main/kotlin/org/genspectrum/lapis/silo/SiloQuery.kt @@ -238,7 +238,9 @@ data class HasAminoAcidMutation(val sequenceName: String, val position: Int) : data class DateBetween(val column: String, val from: LocalDate?, val to: LocalDate?) : SiloFilterExpression("DateBetween") -data class NucleotideInsertionContains(val position: Int, val value: String) : SiloFilterExpression("InsertionContains") +@JsonInclude(JsonInclude.Include.NON_NULL) +data class NucleotideInsertionContains(val position: Int, val value: String, val sequenceName: String?) : + SiloFilterExpression("InsertionContains") data class AminoAcidInsertionContains(val position: Int, val value: String, val sequenceName: String) : SiloFilterExpression( diff --git a/lapis/src/test/kotlin/org/genspectrum/lapis/model/SiloFilterExpressionMapperTest.kt b/lapis/src/test/kotlin/org/genspectrum/lapis/model/SiloFilterExpressionMapperTest.kt index a4407719c..91fa50328 100644 --- a/lapis/src/test/kotlin/org/genspectrum/lapis/model/SiloFilterExpressionMapperTest.kt +++ b/lapis/src/test/kotlin/org/genspectrum/lapis/model/SiloFilterExpressionMapperTest.kt @@ -370,7 +370,7 @@ class SiloFilterExpressionMapperTest { val result = underTest.map(filterParameter) val expected = - And(NucleotideInsertionContains(123, "ABCD"), NucleotideInsertionContains(999, "DEF")) + And(NucleotideInsertionContains(123, "ABCD", "segment"), NucleotideInsertionContains(999, "DEF", null)) assertThat(result, equalTo(expected)) } diff --git a/lapis/src/test/kotlin/org/genspectrum/lapis/model/VariantQueryFacadeTest.kt b/lapis/src/test/kotlin/org/genspectrum/lapis/model/VariantQueryFacadeTest.kt index 98b88af1d..c4ae5b08c 100644 --- a/lapis/src/test/kotlin/org/genspectrum/lapis/model/VariantQueryFacadeTest.kt +++ b/lapis/src/test/kotlin/org/genspectrum/lapis/model/VariantQueryFacadeTest.kt @@ -303,7 +303,15 @@ class VariantQueryFacadeTest { val result = underTest.map(variantQuery) - assertThat(result, equalTo(NucleotideInsertionContains(1234, "GAG"))) + assertThat(result, equalTo(NucleotideInsertionContains(1234, "GAG", null))) + } + + @Test + fun `given a variantQuery with a 'Insertion' expression with sequenceName throws`() { + // COVID variant queries do not support segment name in insertion queries + val variantQuery = "ins_sequence:1234:GAG" + + assertThrows { underTest.map(variantQuery) } } @Test @@ -312,7 +320,7 @@ class VariantQueryFacadeTest { val result = underTest.map(variantQuery) - assertThat(result, equalTo(NucleotideInsertionContains(1234, "GAG"))) + assertThat(result, equalTo(NucleotideInsertionContains(1234, "GAG", null))) } @Test @@ -321,7 +329,7 @@ class VariantQueryFacadeTest { val result = underTest.map(variantQuery) - assertThat(result, equalTo(NucleotideInsertionContains(1234, "GAG"))) + assertThat(result, equalTo(NucleotideInsertionContains(1234, "GAG", null))) } @Test @@ -330,7 +338,7 @@ class VariantQueryFacadeTest { val result = underTest.map(variantQuery) - assertThat(result, equalTo(NucleotideInsertionContains(1234, "G.*A.*G"))) + assertThat(result, equalTo(NucleotideInsertionContains(1234, "G.*A.*G", null))) } @Test diff --git a/lapis/src/test/kotlin/org/genspectrum/lapis/silo/SiloQueryTest.kt b/lapis/src/test/kotlin/org/genspectrum/lapis/silo/SiloQueryTest.kt index b0c056157..c1cdf06be 100644 --- a/lapis/src/test/kotlin/org/genspectrum/lapis/silo/SiloQueryTest.kt +++ b/lapis/src/test/kotlin/org/genspectrum/lapis/silo/SiloQueryTest.kt @@ -485,6 +485,38 @@ class SiloQueryTest { } """, ), + Arguments.of( + NucleotideInsertionContains(1234, "A", "segment"), + """ + { + "type": "InsertionContains", + "position": 1234, + "value": "A", + "sequenceName":"segment" + } + """, + ), + Arguments.of( + NucleotideInsertionContains(1234, "A", null), + """ + { + "type": "InsertionContains", + "position": 1234, + "value": "A" + } + """, + ), + Arguments.of( + AminoAcidInsertionContains(1234, "A", "someGene"), + """ + { + "type": "AminoAcidInsertionContains", + "position": 1234, + "value": "A", + "sequenceName":"someGene" + } + """, + ), Arguments.of( DateBetween("fieldName", LocalDate.of(2021, 3, 31), LocalDate.of(2022, 6, 3)), """