From b01934d0053d97e5891bc28ea6cb178842d5d971 Mon Sep 17 00:00:00 2001 From: pfurio Date: Thu, 22 Feb 2024 11:45:37 +0100 Subject: [PATCH 01/85] catalog: increment sample version when new file is added, #TASK-5668 --- .../db/mongodb/FileMongoDBAdaptor.java | 43 ++++++----- .../db/mongodb/SampleMongoDBAdaptor.java | 73 +++++++++---------- .../mongodb/converters/SampleConverter.java | 5 ++ .../catalog/managers/FileManagerTest.java | 39 ++++++++++ .../managers/IndividualManagerTest.java | 41 ++++++++++- 5 files changed, 139 insertions(+), 62 deletions(-) diff --git a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/FileMongoDBAdaptor.java b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/FileMongoDBAdaptor.java index 3e6e48743c6..4d0e93e23c5 100644 --- a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/FileMongoDBAdaptor.java +++ b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/FileMongoDBAdaptor.java @@ -31,6 +31,7 @@ import org.opencb.opencga.catalog.db.api.FileDBAdaptor; import org.opencb.opencga.catalog.db.api.SampleDBAdaptor; import org.opencb.opencga.catalog.db.mongodb.converters.FileConverter; +import org.opencb.opencga.catalog.db.mongodb.converters.SampleConverter; import org.opencb.opencga.catalog.db.mongodb.iterators.FileCatalogMongoDBIterator; import org.opencb.opencga.catalog.exceptions.CatalogAuthorizationException; import org.opencb.opencga.catalog.exceptions.CatalogDBException; @@ -209,19 +210,15 @@ long insert(ClientSession clientSession, long studyId, File file, List e ObjectMap params = new ObjectMap(SampleDBAdaptor.QueryParams.FILE_IDS.key(), file.getId()); ObjectMap actionMap = new ObjectMap(SampleDBAdaptor.QueryParams.FILE_IDS.key(), BasicUpdateAction.ADD.name()); QueryOptions sampleUpdateOptions = new QueryOptions(Constants.ACTIONS, actionMap); - UpdateDocument sampleUpdateDocument = dbAdaptorFactory.getCatalogSampleDBAdaptor() - .updateFileReferences(params, sampleUpdateOptions); for (List sampleList : sampleListList) { logger.debug("Updating list of fileIds in batch of {} samples...", sampleList.size()); - // Update list of fileIds from sample - Query query = new Query() - .append(SampleDBAdaptor.QueryParams.STUDY_UID.key(), studyId) - .append(SampleDBAdaptor.QueryParams.UID.key(), - sampleList.stream().map(Sample::getUid).collect(Collectors.toList())); - dbAdaptorFactory.getCatalogSampleDBAdaptor().getCollection().update(clientSession, - dbAdaptorFactory.getCatalogSampleDBAdaptor().parseQuery(query, null), - sampleUpdateDocument.toFinalUpdateDocument(), new QueryOptions("multi", true)); + for (Sample sample : sampleList) { + SampleConverter sampleConverter = dbAdaptorFactory.getCatalogSampleDBAdaptor().getSampleConverter(); + Document sampleDocument = sampleConverter.convertToStorageType(sample); + dbAdaptorFactory.getCatalogSampleDBAdaptor().privateUpdate(clientSession, sampleDocument, params, null, + sampleUpdateOptions); + } // Add sample to sampleList samples.addAll(sampleList); @@ -438,8 +435,8 @@ private void updateSampleReferences(ClientSession clientSession, File file, Upda throw new CatalogDBException("Internal error: Expected a list of added, removed or set samples"); } - Bson sampleBsonQuery = null; - UpdateDocument sampleUpdate = null; + Bson sampleBsonQuery; + UpdateDocument sampleUpdate; ObjectMap params = new ObjectMap(SampleDBAdaptor.QueryParams.FILE_IDS.key(), file.getId()); if (!setSamples.isEmpty()) { @@ -466,29 +463,31 @@ private void updateSampleReferences(ClientSession clientSession, File file, Upda Query query = new Query() .append(SampleDBAdaptor.QueryParams.STUDY_UID.key(), file.getStudyUid()) .append(SampleDBAdaptor.QueryParams.UID.key(), addedSamples.getAsLongList(file.getId())); - sampleBsonQuery = dbAdaptorFactory.getCatalogSampleDBAdaptor().parseQuery(query, null); + List sampleList = dbAdaptorFactory.getCatalogSampleDBAdaptor().nativeGet(clientSession, query, + dbAdaptorFactory.getCatalogSampleDBAdaptor().SAMPLE_FETCH_FOR_UPDATE_OPTIONS).getResults(); ObjectMap actionMap = new ObjectMap(SampleDBAdaptor.QueryParams.FILE_IDS.key(), BasicUpdateAction.ADD.name()); QueryOptions sampleUpdateOptions = new QueryOptions(Constants.ACTIONS, actionMap); - sampleUpdate = dbAdaptorFactory.getCatalogSampleDBAdaptor().updateFileReferences(params, sampleUpdateOptions); - - dbAdaptorFactory.getCatalogSampleDBAdaptor().getCollection().update(clientSession, sampleBsonQuery, - sampleUpdate.toFinalUpdateDocument(), new QueryOptions(MongoDBCollection.MULTI, true)); + for (Document sampleDocument : sampleList) { + dbAdaptorFactory.getCatalogSampleDBAdaptor().privateUpdate(clientSession, sampleDocument, params, null, + sampleUpdateOptions); + } } if (removedSamples != null && !removedSamples.isEmpty()) { Query query = new Query() .append(SampleDBAdaptor.QueryParams.STUDY_UID.key(), file.getStudyUid()) .append(SampleDBAdaptor.QueryParams.UID.key(), removedSamples.getAsLongList(file.getId())); - sampleBsonQuery = dbAdaptorFactory.getCatalogSampleDBAdaptor().parseQuery(query, null); + List sampleList = dbAdaptorFactory.getCatalogSampleDBAdaptor().nativeGet(clientSession, query, + dbAdaptorFactory.getCatalogSampleDBAdaptor().SAMPLE_FETCH_FOR_UPDATE_OPTIONS).getResults(); ObjectMap actionMap = new ObjectMap(SampleDBAdaptor.QueryParams.FILE_IDS.key(), BasicUpdateAction.REMOVE.name()); QueryOptions sampleUpdateOptions = new QueryOptions(Constants.ACTIONS, actionMap); - sampleUpdate = dbAdaptorFactory.getCatalogSampleDBAdaptor().updateFileReferences(params, sampleUpdateOptions); - - dbAdaptorFactory.getCatalogSampleDBAdaptor().getCollection().update(clientSession, sampleBsonQuery, - sampleUpdate.toFinalUpdateDocument(), new QueryOptions(MongoDBCollection.MULTI, true)); + for (Document sampleDocument : sampleList) { + dbAdaptorFactory.getCatalogSampleDBAdaptor().privateUpdate(clientSession, sampleDocument, params, null, + sampleUpdateOptions); + } } } } diff --git a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/SampleMongoDBAdaptor.java b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/SampleMongoDBAdaptor.java index 6d7bd764c57..22ffb20c77e 100644 --- a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/SampleMongoDBAdaptor.java +++ b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/SampleMongoDBAdaptor.java @@ -83,6 +83,10 @@ public class SampleMongoDBAdaptor extends AnnotationMongoDBAdaptor imple private final IndividualMongoDBAdaptor individualDBAdaptor; private final VersionedMongoDBAdaptor versionedMongoDBAdaptor; + final QueryOptions SAMPLE_FETCH_FOR_UPDATE_OPTIONS = new QueryOptions(QueryOptions.INCLUDE, + Arrays.asList(QueryParams.ID.key(), QueryParams.UID.key(), QueryParams.VERSION.key(), QueryParams.STUDY_UID.key(), + PRIVATE_INDIVIDUAL_UID)); + public SampleMongoDBAdaptor(MongoDBCollection sampleCollection, MongoDBCollection archiveSampleCollection, MongoDBCollection deletedSampleCollection, Configuration configuration, MongoDBAdaptorFactory dbAdaptorFactory) { @@ -91,7 +95,7 @@ public SampleMongoDBAdaptor(MongoDBCollection sampleCollection, MongoDBCollectio this.sampleCollection = sampleCollection; this.archiveSampleCollection = archiveSampleCollection; this.deletedSampleCollection = deletedSampleCollection; - sampleConverter = new SampleConverter(); + this.sampleConverter = new SampleConverter(); individualDBAdaptor = dbAdaptorFactory.getCatalogIndividualDBAdaptor(); this.versionedMongoDBAdaptor = new VersionedMongoDBAdaptor(sampleCollection, archiveSampleCollection, deletedSampleCollection); } @@ -105,6 +109,10 @@ public MongoDBCollection getArchiveSampleCollection() { return archiveSampleCollection; } + public SampleConverter getSampleConverter() { + return sampleConverter; + } + /* * Samples methods * *************************** @@ -245,10 +253,7 @@ public OpenCGAResult update(long id, ObjectMap parameters, QueryOptions queryOpt public OpenCGAResult update(long uid, ObjectMap parameters, List variableSetList, QueryOptions queryOptions) throws CatalogDBException, CatalogParameterException, CatalogAuthorizationException { Query query = new Query(QueryParams.UID.key(), uid); - QueryOptions options = new QueryOptions(QueryOptions.INCLUDE, - Arrays.asList(QueryParams.ID.key(), QueryParams.UID.key(), QueryParams.VERSION.key(), QueryParams.STUDY_UID.key(), - PRIVATE_INDIVIDUAL_UID)); - OpenCGAResult documentResult = nativeGet(query, options); + OpenCGAResult documentResult = nativeGet(query, SAMPLE_FETCH_FOR_UPDATE_OPTIONS); if (documentResult.getNumResults() == 0) { throw new CatalogDBException("Could not update sample. Sample uid '" + uid + "' not found."); } @@ -310,7 +315,6 @@ OpenCGAResult privateUpdate(ClientSession clientSession, Document sample long sampleUid = sampleDocument.getLong(QueryParams.UID.key()); int version = sampleDocument.getInteger(QueryParams.VERSION.key()); long studyUid = sampleDocument.getLong(QueryParams.STUDY_UID.key()); - long individualUid = sampleDocument.getLong(PRIVATE_INDIVIDUAL_UID); Query tmpQuery = new Query() .append(QueryParams.STUDY_UID.key(), studyUid) @@ -335,9 +339,10 @@ OpenCGAResult privateUpdate(ClientSession clientSession, Document sample Bson finalQuery = parseQuery(tmpQuery); logger.debug("Sample update: query : {}, update: {}", finalQuery.toBsonDocument(), sampleUpdate.toBsonDocument()); - result = sampleCollection.update(clientSession, finalQuery, sampleUpdate, new QueryOptions("multi", true)); + result = sampleCollection.update(clientSession, finalQuery, sampleUpdate, new QueryOptions(MongoDBCollection.MULTI, true)); if (updateParams.getSet().containsKey(PRIVATE_INDIVIDUAL_UID)) { + long individualUid = sampleDocument.getLong(PRIVATE_INDIVIDUAL_UID); long newIndividualUid = updateParams.getSet().getLong(PRIVATE_INDIVIDUAL_UID); // If the sample has been associated a different individual @@ -612,6 +617,30 @@ UpdateDocument parseAndValidateUpdateParams(ClientSession clientSession, long st document.getSet().put(QueryParams.ID.key(), parameters.get(QueryParams.ID.key())); } + // Check if the tags exist. + if (parameters.containsKey(QueryParams.FILE_IDS.key())) { + List fileIdList = parameters.getAsStringList(QueryParams.FILE_IDS.key()); + + if (!fileIdList.isEmpty()) { + Map actionMap = queryOptions.getMap(Constants.ACTIONS, new HashMap<>()); + ParamUtils.BasicUpdateAction operation = + ParamUtils.BasicUpdateAction.from(actionMap, QueryParams.FILE_IDS.key(), ParamUtils.BasicUpdateAction.ADD); + switch (operation) { + case SET: + document.getSet().put(QueryParams.FILE_IDS.key(), fileIdList); + break; + case REMOVE: + document.getPullAll().put(QueryParams.FILE_IDS.key(), fileIdList); + break; + case ADD: + document.getAddToSet().put(QueryParams.FILE_IDS.key(), fileIdList); + break; + default: + throw new IllegalArgumentException("Unknown update action " + operation); + } + } + } + if (parameters.containsKey(QueryParams.INTERNAL_RGA.key())) { RgaIndex rgaIndex = parameters.get(QueryParams.INTERNAL_RGA.key(), RgaIndex.class); rgaIndex.setDate(TimeUtils.getTime()); @@ -698,36 +727,6 @@ void fixPhenotypesForRemoval(ObjectMap parameters) { parameters.put(QueryParams.PHENOTYPES.key(), phenotypeParamList); } - UpdateDocument updateFileReferences(ObjectMap parameters, QueryOptions queryOptions) { - UpdateDocument document = new UpdateDocument(); - - // Check if the tags exist. - if (parameters.containsKey(QueryParams.FILE_IDS.key())) { - List fileIdList = parameters.getAsStringList(QueryParams.FILE_IDS.key()); - - if (!fileIdList.isEmpty()) { - Map actionMap = queryOptions.getMap(Constants.ACTIONS, new HashMap<>()); - ParamUtils.BasicUpdateAction operation = - ParamUtils.BasicUpdateAction.from(actionMap, QueryParams.FILE_IDS.key(), ParamUtils.BasicUpdateAction.ADD); - switch (operation) { - case SET: - document.getSet().put(QueryParams.FILE_IDS.key(), fileIdList); - break; - case REMOVE: - document.getPullAll().put(QueryParams.FILE_IDS.key(), fileIdList); - break; - case ADD: - document.getAddToSet().put(QueryParams.FILE_IDS.key(), fileIdList); - break; - default: - throw new IllegalArgumentException("Unknown update action " + operation); - } - } - } - - return document; - } - @Override public long getStudyId(long sampleId) throws CatalogDBException { Bson query = new Document(PRIVATE_UID, sampleId); diff --git a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/converters/SampleConverter.java b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/converters/SampleConverter.java index dad025bae39..582509ad581 100644 --- a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/converters/SampleConverter.java +++ b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/converters/SampleConverter.java @@ -37,6 +37,11 @@ public SampleConverter() { individualConverter = new IndividualConverter(); } + @Override + public Document convertToStorageType(Sample object) { + return convertToStorageType(object, null); + } + @Override public Document convertToStorageType(Sample object, List variableSetList) { Document document = super.convertToStorageType(object, variableSetList); diff --git a/opencga-catalog/src/test/java/org/opencb/opencga/catalog/managers/FileManagerTest.java b/opencga-catalog/src/test/java/org/opencb/opencga/catalog/managers/FileManagerTest.java index 77703e0c2ad..c6c8dc91c61 100644 --- a/opencga-catalog/src/test/java/org/opencb/opencga/catalog/managers/FileManagerTest.java +++ b/opencga-catalog/src/test/java/org/opencb/opencga/catalog/managers/FileManagerTest.java @@ -648,6 +648,45 @@ public void testLinkFilePassingNoDirectoryPath() throws CatalogException, URISyn assertEquals(File.Type.FILE, link.first().getType()); } + @Test + public void changeNameTest() throws CatalogException { + // Link VCF file. This VCF file will automatically create sample NA19600 + String vcfFile = getClass().getResource("/biofiles/variant-test-file.vcf.gz").getFile(); + catalogManager.getFileManager().link(studyFqn, new FileLinkParams(vcfFile, "data/", "", "", null, null, null, null, null), true, token); + + Query query = new Query(SampleDBAdaptor.QueryParams.FILE_IDS.key(), "variant-test-file.vcf.gz"); + QueryOptions options = new QueryOptions(QueryOptions.INCLUDE, SampleDBAdaptor.QueryParams.FILE_IDS.key()); + OpenCGAResult sampleResult = catalogManager.getSampleManager().search(studyFqn, query, options, token); + assertEquals(4, sampleResult.getNumResults()); + for (Sample sample : sampleResult.getResults()) { + assertEquals(1, sample.getFileIds().size()); + assertEquals("data:variant-test-file.vcf.gz", sample.getFileIds().get(0)); + assertEquals(1, sample.getVersion()); + } + + // Rename file + FileUpdateParams updateParams = new FileUpdateParams().setName("variant_test.vcf.gz"); + catalogManager.getFileManager().update(studyFqn, "variant-test-file.vcf.gz", updateParams, null, token); + + assertThrows("not found", CatalogException.class, () -> catalogManager.getFileManager().get(studyFqn, "variant-test-file.vcf.gz", null, token)); + File file = catalogManager.getFileManager().get(studyFqn, updateParams.getName(), FileManager.INCLUDE_FILE_URI_PATH, token).first(); + assertEquals("data:" + updateParams.getName(), file.getId()); + assertEquals("data/" + updateParams.getName(), file.getPath()); + assertEquals(updateParams.getName(), file.getName()); + + sampleResult = catalogManager.getSampleManager().search(studyFqn, query, options, token); + assertEquals(0, sampleResult.getNumResults()); + + query = new Query(SampleDBAdaptor.QueryParams.FILE_IDS.key(), updateParams.getName()); + sampleResult = catalogManager.getSampleManager().search(studyFqn, query, options, token); + assertEquals(4, sampleResult.getNumResults()); + for (Sample sample : sampleResult.getResults()) { + assertEquals(1, sample.getFileIds().size()); + assertEquals("data:" + updateParams.getName(), sample.getFileIds().get(0)); + assertEquals(2, sample.getVersion()); + } + } + @Test public void testAssociateSamples() throws CatalogException, URISyntaxException { URI uri = getClass().getResource("/biofiles/variant-test-file-dot-names.vcf.gz").toURI(); diff --git a/opencga-catalog/src/test/java/org/opencb/opencga/catalog/managers/IndividualManagerTest.java b/opencga-catalog/src/test/java/org/opencb/opencga/catalog/managers/IndividualManagerTest.java index 0ac883fe91a..1f01b9d1acd 100644 --- a/opencga-catalog/src/test/java/org/opencb/opencga/catalog/managers/IndividualManagerTest.java +++ b/opencga-catalog/src/test/java/org/opencb/opencga/catalog/managers/IndividualManagerTest.java @@ -13,6 +13,7 @@ import org.opencb.commons.datastore.core.Query; import org.opencb.commons.datastore.core.QueryOptions; import org.opencb.opencga.catalog.db.api.IndividualDBAdaptor; +import org.opencb.opencga.catalog.db.api.SampleDBAdaptor; import org.opencb.opencga.catalog.exceptions.CatalogException; import org.opencb.opencga.catalog.utils.Constants; import org.opencb.opencga.catalog.utils.ParamUtils; @@ -21,6 +22,7 @@ import org.opencb.opencga.core.models.clinical.ClinicalAnalysisUpdateParams; import org.opencb.opencga.core.models.common.AnnotationSet; import org.opencb.opencga.core.models.family.Family; +import org.opencb.opencga.core.models.file.FileLinkParams; import org.opencb.opencga.core.models.individual.Individual; import org.opencb.opencga.core.models.individual.IndividualQualityControl; import org.opencb.opencga.core.models.individual.IndividualReferenceParam; @@ -972,7 +974,7 @@ public void memberReferenceTest() throws CatalogException { // Update individual 2 individual2 = catalogManager.getIndividualManager().update(studyFqn, individual2.getId(), new IndividualUpdateParams() - .setName("blabla"), options, token).first(); + .setName("blabla"), options, token).first(); assertEquals(2, individual2.getSamples().size()); assertEquals(3, individual2.getVersion()); assertEquals(2, individual2.getSamples().stream().map(Sample::getVersion).filter(v -> v == 1).count()); @@ -996,7 +998,7 @@ public void memberReferenceTest() throws CatalogException { // Update id from individual1 individual1 = catalogManager.getIndividualManager().update(studyFqn, individual1.getId(), new IndividualUpdateParams() - .setId("blabla"), options, token).first(); + .setId("blabla"), options, token).first(); assertEquals(2, individual1.getSamples().size()); assertEquals(3, individual1.getVersion()); assertEquals(2, individual1.getSamples().stream().map(Sample::getVersion).filter(v -> v == 2).count()); @@ -1038,7 +1040,7 @@ public void updateInUseInCATest() throws CatalogException { // locked true ClinicalAnalysis case3 = DummyModelUtils.getDummyClinicalAnalysis(family.getMembers().get(0), family, null) - .setLocked(true); + .setLocked(true); case1 = catalogManager.getClinicalAnalysisManager().create(studyFqn, case1, options, token).first(); assertFalse(case1.isLocked()); @@ -1129,4 +1131,37 @@ public void updateDeleteInUseInCATest() throws CatalogException { } } + @Test + // TASK-5668 + public void viewSampleFilesFromIndividualTest() throws CatalogException { + // Link VCF file. This VCF file will automatically create sample NA19600 + String vcfFile = getClass().getResource("/biofiles/variant-test-file.vcf.gz").getFile(); + catalogManager.getFileManager().link(studyFqn, new FileLinkParams(vcfFile, "", "", "", null, null, null, null, null), false, token); + + Sample sample = catalogManager.getSampleManager().get(studyFqn, "NA19600", + new QueryOptions(QueryOptions.INCLUDE, SampleDBAdaptor.QueryParams.FILE_IDS.key()), token).first(); + assertEquals(1, sample.getFileIds().size()); + assertEquals("variant-test-file.vcf.gz", sample.getFileIds().get(0)); + + // Create individual + catalogManager.getIndividualManager().create(studyFqn, new Individual().setId("individual"), Collections.singletonList(sample.getId()), + QueryOptions.empty(), token); + Individual individual = catalogManager.getIndividualManager().get(studyFqn, "individual", QueryOptions.empty(), token).first(); + assertEquals(1, individual.getSamples().get(0).getFileIds().size()); + assertEquals("variant-test-file.vcf.gz", individual.getSamples().get(0).getFileIds().get(0)); + + // Link BAM file (related to NA19600 sample) + String bamFile = getClass().getResource("/biofiles/NA19600.chrom20.small.bam").getFile(); + catalogManager.getFileManager().link(studyFqn, new FileLinkParams(bamFile, "", "", "", null, null, null, null, null), false, token); + + sample = catalogManager.getSampleManager().get(studyFqn, "NA19600", + new QueryOptions(QueryOptions.INCLUDE, SampleDBAdaptor.QueryParams.FILE_IDS.key()), token).first(); + assertEquals(2, sample.getFileIds().size()); + assertTrue(Arrays.asList("variant-test-file.vcf.gz", "NA19600.chrom20.small.bam").containsAll(sample.getFileIds())); + + individual = catalogManager.getIndividualManager().get(studyFqn, "individual", QueryOptions.empty(), token).first(); + assertEquals(2, individual.getSamples().get(0).getFileIds().size()); + assertTrue(Arrays.asList("variant-test-file.vcf.gz", "NA19600.chrom20.small.bam").containsAll(individual.getSamples().get(0).getFileIds())); + } + } From 6757c74dd8bfebe1d7a0eb0240aff0d8ad2491f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacobo=20Coll=20Morag=C3=B3n?= Date: Wed, 28 Feb 2024 15:43:23 +0000 Subject: [PATCH 02/85] storage: Do not fail on missing trios. Do not execute family-index on each variant-index. #TASK-2306 --- .../opencga/analysis/tools/OpenCgaTool.java | 2 +- .../manager/VariantStorageManager.java | 22 +++++++++++-- .../VariantFileDeleteOperationTool.java | 2 +- .../VariantFileIndexJobLauncherTool.java | 4 +-- .../operations/VariantIndexOperationTool.java | 32 +------------------ .../operations/VariantPruneOperationTool.java | 2 +- .../VariantSampleDeleteOperationTool.java | 2 +- ...orageMetadataSynchronizeOperationTool.java | 2 +- .../VariantStudyDeleteOperationTool.java | 2 +- .../analysis/variant/VariantAnalysisTest.java | 1 + .../manager/VariantOperationsTest.java | 19 +++++++++-- .../operations/PlatinumFileIndexerTest.java | 4 +-- ...ariantFileIndexerOperationManagerTest.java | 4 +-- .../VariantVirtualFileIndexTest.java | 2 +- .../AnalysisVariantCommandExecutor.java | 13 +------- ...erationsVariantStorageCommandExecutor.java | 23 +++++-------- .../opencga/catalog/managers/JobManager.java | 7 ++-- .../client/rest/clients/VariantClient.java | 2 +- .../rest/clients/VariantOperationClient.java | 16 +++++----- .../opencga/core/api/ParamConstants.java | 2 ++ .../opencb/opencga/core/config/Execution.java | 11 +++++++ .../variant/VariantAggregateFamilyParams.java | 6 ++++ .../variant/VariantAggregateParams.java | 6 +++- .../VariantAnnotationDeleteParams.java | 2 ++ .../variant/VariantAnnotationSaveParams.java | 2 ++ .../variant/VariantConfigureParams.java | 2 +- .../variant/VariantFamilyIndexParams.java | 1 + .../variant/VariantFileDeleteParams.java | 2 +- .../VariantFileIndexJobLauncherParams.java | 2 +- .../variant/VariantIndexParams.java | 6 ++-- .../variant/VariantPruneParams.java | 2 +- .../variant/VariantSampleDeleteParams.java | 2 +- ...riantStorageMetadataSynchronizeParams.java | 2 +- .../variant/VariantStudyDeleteParams.java | 2 +- .../src/main/resources/configuration.yml | 4 ++- .../rest/analysis/VariantWebService.java | 14 ++------ 36 files changed, 115 insertions(+), 114 deletions(-) rename opencga-core/src/main/java/org/opencb/opencga/core/models/{ => operations}/variant/VariantConfigureParams.java (85%) rename opencga-core/src/main/java/org/opencb/opencga/core/models/{ => operations}/variant/VariantFileDeleteParams.java (95%) rename opencga-core/src/main/java/org/opencb/opencga/core/models/{ => operations}/variant/VariantFileIndexJobLauncherParams.java (97%) rename opencga-core/src/main/java/org/opencb/opencga/core/models/{ => operations}/variant/VariantIndexParams.java (98%) rename opencga-core/src/main/java/org/opencb/opencga/core/models/{ => operations}/variant/VariantPruneParams.java (93%) rename opencga-core/src/main/java/org/opencb/opencga/core/models/{ => operations}/variant/VariantSampleDeleteParams.java (96%) rename opencga-core/src/main/java/org/opencb/opencga/core/models/{ => operations}/variant/VariantStorageMetadataSynchronizeParams.java (92%) rename opencga-core/src/main/java/org/opencb/opencga/core/models/{ => operations}/variant/VariantStudyDeleteParams.java (95%) diff --git a/opencga-analysis/src/main/java/org/opencb/opencga/analysis/tools/OpenCgaTool.java b/opencga-analysis/src/main/java/org/opencb/opencga/analysis/tools/OpenCgaTool.java index 7769315137b..c80a799a050 100644 --- a/opencga-analysis/src/main/java/org/opencb/opencga/analysis/tools/OpenCgaTool.java +++ b/opencga-analysis/src/main/java/org/opencb/opencga/analysis/tools/OpenCgaTool.java @@ -460,7 +460,7 @@ protected final void step(String stepId, StepRunnable step) throws ToolException } catch (ToolException e) { throw e; } catch (Exception e) { - throw new ToolException("Exception from step " + stepId, e); + throw new ToolException("Exception from step '" + stepId + "'", e); } } else { privateLogger.info("------- Skip step " + stepId + " -------"); diff --git a/opencga-analysis/src/main/java/org/opencb/opencga/analysis/variant/manager/VariantStorageManager.java b/opencga-analysis/src/main/java/org/opencb/opencga/analysis/variant/manager/VariantStorageManager.java index bf0db6f34eb..33de681f215 100644 --- a/opencga-analysis/src/main/java/org/opencb/opencga/analysis/variant/manager/VariantStorageManager.java +++ b/opencga-analysis/src/main/java/org/opencb/opencga/analysis/variant/manager/VariantStorageManager.java @@ -68,7 +68,6 @@ import org.opencb.opencga.core.models.sample.SamplePermissions; import org.opencb.opencga.core.models.study.Study; import org.opencb.opencga.core.models.study.StudyPermissions; -import org.opencb.opencga.core.models.variant.VariantPruneParams; import org.opencb.opencga.core.response.OpenCGAResult; import org.opencb.opencga.core.response.VariantQueryResult; import org.opencb.opencga.core.tools.ToolParams; @@ -408,7 +407,6 @@ public DataResult familyIndex(String study, List familiesStr, bool throws CatalogException, StorageEngineException { return secureOperation(VariantFamilyIndexOperationTool.ID, study, params, token, engine -> { List trios = new LinkedList<>(); - List events = new LinkedList<>(); VariantStorageMetadataManager metadataManager = engine.getMetadataManager(); VariantCatalogQueryUtils catalogUtils = new VariantCatalogQueryUtils(catalogManager); if (familiesStr.size() == 1 && familiesStr.get(0).equals(VariantQueryUtils.ALL)) { @@ -425,7 +423,7 @@ public DataResult familyIndex(String study, List familiesStr, bool } DataResult dataResult = engine.familyIndex(study, trios, params); getSynchronizer(engine).synchronizeCatalogSamplesFromStorage(study, trios.stream() - .flatMap(t->t.toList().stream()) + .flatMap(t -> t.toList().stream()) .collect(Collectors.toList()), token); return dataResult; }); @@ -441,11 +439,29 @@ public DataResult familyIndexBySamples(String study, Collection sa throws CatalogException, StorageEngineException { return secureOperation(VariantFamilyIndexOperationTool.ID, study, params, token, engine -> { Collection thisSamples = samples; + boolean allSamples; if (CollectionUtils.size(thisSamples) == 1 && thisSamples.iterator().next().equals(ParamConstants.ALL)) { thisSamples = getIndexedSamples(study, token); + allSamples = true; + } else { + allSamples = false; } List trios = catalogUtils.getTriosFromSamples(study, engine.getMetadataManager(), thisSamples, token); + if (trios.isEmpty()) { + String msg; + if (thisSamples.size() > 6) { + msg = "No trios found for " + thisSamples.size() + " samples"; + } else { + msg = "No trios found for samples " + thisSamples; + } + if (allSamples) { + logger.info(msg); + return new DataResult<>(0, Collections.singletonList(new Event(Event.Type.INFO, msg)), 0, Collections.emptyList(), 0); + } else { + throw new StorageEngineException(msg); + } + } DataResult dataResult = engine.familyIndex(study, trios, params); getSynchronizer(engine).synchronizeCatalogSamplesFromStorage(study, trios.stream() .flatMap(t -> t.toList().stream()) diff --git a/opencga-analysis/src/main/java/org/opencb/opencga/analysis/variant/operations/VariantFileDeleteOperationTool.java b/opencga-analysis/src/main/java/org/opencb/opencga/analysis/variant/operations/VariantFileDeleteOperationTool.java index bb3cb4d3f3a..8a321c24ff3 100644 --- a/opencga-analysis/src/main/java/org/opencb/opencga/analysis/variant/operations/VariantFileDeleteOperationTool.java +++ b/opencga-analysis/src/main/java/org/opencb/opencga/analysis/variant/operations/VariantFileDeleteOperationTool.java @@ -20,7 +20,7 @@ import org.apache.solr.common.StringUtils; import org.opencb.opencga.core.exceptions.ToolException; import org.opencb.opencga.core.models.common.Enums; -import org.opencb.opencga.core.models.variant.VariantFileDeleteParams; +import org.opencb.opencga.core.models.operations.variant.VariantFileDeleteParams; import org.opencb.opencga.core.tools.annotations.Tool; import org.opencb.opencga.core.tools.annotations.ToolParams; import org.opencb.opencga.storage.core.variant.VariantStorageOptions; diff --git a/opencga-analysis/src/main/java/org/opencb/opencga/analysis/variant/operations/VariantFileIndexJobLauncherTool.java b/opencga-analysis/src/main/java/org/opencb/opencga/analysis/variant/operations/VariantFileIndexJobLauncherTool.java index c548f0fbbca..0495432ae21 100644 --- a/opencga-analysis/src/main/java/org/opencb/opencga/analysis/variant/operations/VariantFileIndexJobLauncherTool.java +++ b/opencga-analysis/src/main/java/org/opencb/opencga/analysis/variant/operations/VariantFileIndexJobLauncherTool.java @@ -15,8 +15,8 @@ import org.opencb.opencga.core.models.file.FileInternal; import org.opencb.opencga.core.models.file.VariantIndexStatus; import org.opencb.opencga.core.models.job.Job; -import org.opencb.opencga.core.models.variant.VariantFileIndexJobLauncherParams; -import org.opencb.opencga.core.models.variant.VariantIndexParams; +import org.opencb.opencga.core.models.operations.variant.VariantFileIndexJobLauncherParams; +import org.opencb.opencga.core.models.operations.variant.VariantIndexParams; import org.opencb.opencga.core.response.OpenCGAResult; import org.opencb.opencga.core.tools.annotations.Tool; import org.opencb.opencga.core.tools.annotations.ToolParams; diff --git a/opencga-analysis/src/main/java/org/opencb/opencga/analysis/variant/operations/VariantIndexOperationTool.java b/opencga-analysis/src/main/java/org/opencb/opencga/analysis/variant/operations/VariantIndexOperationTool.java index cce9fc91e8a..70a882d4d80 100644 --- a/opencga-analysis/src/main/java/org/opencb/opencga/analysis/variant/operations/VariantIndexOperationTool.java +++ b/opencga-analysis/src/main/java/org/opencb/opencga/analysis/variant/operations/VariantIndexOperationTool.java @@ -17,13 +17,9 @@ package org.opencb.opencga.analysis.variant.operations; import io.jsonwebtoken.lang.Collections; -import org.opencb.commons.datastore.core.Query; -import org.opencb.commons.datastore.core.QueryOptions; -import org.opencb.opencga.catalog.db.api.FileDBAdaptor; import org.opencb.opencga.core.exceptions.ToolException; import org.opencb.opencga.core.models.common.Enums; -import org.opencb.opencga.core.models.variant.VariantIndexParams; -import org.opencb.opencga.core.response.OpenCGAResult; +import org.opencb.opencga.core.models.operations.variant.VariantIndexParams; import org.opencb.opencga.core.tools.annotations.Tool; import org.opencb.opencga.core.tools.annotations.ToolParams; import org.opencb.opencga.storage.core.StoragePipelineResult; @@ -34,9 +30,7 @@ import java.net.URI; import java.nio.file.Files; import java.util.ArrayList; -import java.util.HashSet; import java.util.List; -import java.util.Set; import static org.opencb.opencga.analysis.variant.manager.operations.VariantFileIndexerOperationManager.*; @@ -112,9 +106,6 @@ protected void check() throws Exception { protected List getSteps() { List steps = new ArrayList<>(); steps.add(getId()); - if (indexParams.isFamily()) { - steps.add("family-index"); - } return steps; } @@ -155,26 +146,5 @@ protected void run() throws Exception { } } }); - - if (indexParams.isFamily()) { - step("family-index", () -> { - if (inputFiles.isEmpty()) { - // Nothing to do! - return; - } - OpenCGAResult fileResult = getCatalogManager().getFileManager() - .search(study, - new Query(FileDBAdaptor.QueryParams.URI.key(), inputFiles), - new QueryOptions(QueryOptions.INCLUDE, FileDBAdaptor.QueryParams.SAMPLE_IDS.key()), getToken()); - - Set samples = new HashSet<>(); - for (org.opencb.opencga.core.models.file.File file : fileResult.getResults()) { - samples.addAll(file.getSampleIds()); - } - if (!samples.isEmpty()) { - variantStorageManager.familyIndexBySamples(study, samples, params, getToken()); - } - }); - } } } diff --git a/opencga-analysis/src/main/java/org/opencb/opencga/analysis/variant/operations/VariantPruneOperationTool.java b/opencga-analysis/src/main/java/org/opencb/opencga/analysis/variant/operations/VariantPruneOperationTool.java index faaee5e681a..58838a2ea1e 100644 --- a/opencga-analysis/src/main/java/org/opencb/opencga/analysis/variant/operations/VariantPruneOperationTool.java +++ b/opencga-analysis/src/main/java/org/opencb/opencga/analysis/variant/operations/VariantPruneOperationTool.java @@ -1,7 +1,7 @@ package org.opencb.opencga.analysis.variant.operations; import org.opencb.opencga.core.models.common.Enums; -import org.opencb.opencga.core.models.variant.VariantPruneParams; +import org.opencb.opencga.core.models.operations.variant.VariantPruneParams; import org.opencb.opencga.core.tools.annotations.Tool; import org.opencb.opencga.core.tools.annotations.ToolParams; diff --git a/opencga-analysis/src/main/java/org/opencb/opencga/analysis/variant/operations/VariantSampleDeleteOperationTool.java b/opencga-analysis/src/main/java/org/opencb/opencga/analysis/variant/operations/VariantSampleDeleteOperationTool.java index 14c456cc592..067367a3f28 100644 --- a/opencga-analysis/src/main/java/org/opencb/opencga/analysis/variant/operations/VariantSampleDeleteOperationTool.java +++ b/opencga-analysis/src/main/java/org/opencb/opencga/analysis/variant/operations/VariantSampleDeleteOperationTool.java @@ -20,7 +20,7 @@ import org.apache.solr.common.StringUtils; import org.opencb.opencga.core.exceptions.ToolException; import org.opencb.opencga.core.models.common.Enums; -import org.opencb.opencga.core.models.variant.VariantSampleDeleteParams; +import org.opencb.opencga.core.models.operations.variant.VariantSampleDeleteParams; import org.opencb.opencga.core.tools.annotations.Tool; import org.opencb.opencga.core.tools.annotations.ToolParams; import org.opencb.opencga.storage.core.variant.VariantStorageOptions; diff --git a/opencga-analysis/src/main/java/org/opencb/opencga/analysis/variant/operations/VariantStorageMetadataSynchronizeOperationTool.java b/opencga-analysis/src/main/java/org/opencb/opencga/analysis/variant/operations/VariantStorageMetadataSynchronizeOperationTool.java index 62b69d96d34..193c92d359c 100644 --- a/opencga-analysis/src/main/java/org/opencb/opencga/analysis/variant/operations/VariantStorageMetadataSynchronizeOperationTool.java +++ b/opencga-analysis/src/main/java/org/opencb/opencga/analysis/variant/operations/VariantStorageMetadataSynchronizeOperationTool.java @@ -3,7 +3,7 @@ import org.opencb.opencga.catalog.exceptions.CatalogAuthenticationException; import org.opencb.opencga.core.api.ParamConstants; import org.opencb.opencga.core.models.common.Enums; -import org.opencb.opencga.core.models.variant.VariantStorageMetadataSynchronizeParams; +import org.opencb.opencga.core.models.operations.variant.VariantStorageMetadataSynchronizeParams; import org.opencb.opencga.core.tools.annotations.Tool; import org.opencb.opencga.core.tools.annotations.ToolParams; diff --git a/opencga-analysis/src/main/java/org/opencb/opencga/analysis/variant/operations/VariantStudyDeleteOperationTool.java b/opencga-analysis/src/main/java/org/opencb/opencga/analysis/variant/operations/VariantStudyDeleteOperationTool.java index d24a21668e2..643c2c989d8 100644 --- a/opencga-analysis/src/main/java/org/opencb/opencga/analysis/variant/operations/VariantStudyDeleteOperationTool.java +++ b/opencga-analysis/src/main/java/org/opencb/opencga/analysis/variant/operations/VariantStudyDeleteOperationTool.java @@ -19,7 +19,7 @@ import org.apache.solr.common.StringUtils; import org.opencb.opencga.core.exceptions.ToolException; import org.opencb.opencga.core.models.common.Enums; -import org.opencb.opencga.core.models.variant.VariantStudyDeleteParams; +import org.opencb.opencga.core.models.operations.variant.VariantStudyDeleteParams; import org.opencb.opencga.core.tools.annotations.Tool; import org.opencb.opencga.core.tools.annotations.ToolParams; import org.opencb.opencga.storage.core.variant.VariantStorageOptions; diff --git a/opencga-analysis/src/test/java/org/opencb/opencga/analysis/variant/VariantAnalysisTest.java b/opencga-analysis/src/test/java/org/opencb/opencga/analysis/variant/VariantAnalysisTest.java index fafdb74d983..718d28fee1f 100644 --- a/opencga-analysis/src/test/java/org/opencb/opencga/analysis/variant/VariantAnalysisTest.java +++ b/opencga-analysis/src/test/java/org/opencb/opencga/analysis/variant/VariantAnalysisTest.java @@ -71,6 +71,7 @@ import org.opencb.opencga.core.models.individual.Individual; import org.opencb.opencga.core.models.individual.IndividualInternal; import org.opencb.opencga.core.models.individual.Location; +import org.opencb.opencga.core.models.operations.variant.VariantIndexParams; import org.opencb.opencga.core.models.project.ProjectCreateParams; import org.opencb.opencga.core.models.project.ProjectOrganism; import org.opencb.opencga.core.models.sample.Sample; diff --git a/opencga-analysis/src/test/java/org/opencb/opencga/analysis/variant/manager/VariantOperationsTest.java b/opencga-analysis/src/test/java/org/opencb/opencga/analysis/variant/manager/VariantOperationsTest.java index a5ec92aafec..14c09547876 100644 --- a/opencga-analysis/src/test/java/org/opencb/opencga/analysis/variant/manager/VariantOperationsTest.java +++ b/opencga-analysis/src/test/java/org/opencb/opencga/analysis/variant/manager/VariantOperationsTest.java @@ -54,8 +54,8 @@ import org.opencb.opencga.core.models.project.ProjectOrganism; import org.opencb.opencga.core.models.sample.*; import org.opencb.opencga.core.models.user.Account; -import org.opencb.opencga.core.models.variant.VariantIndexParams; -import org.opencb.opencga.core.models.variant.VariantStorageMetadataSynchronizeParams; +import org.opencb.opencga.core.models.operations.variant.VariantIndexParams; +import org.opencb.opencga.core.models.operations.variant.VariantStorageMetadataSynchronizeParams; import org.opencb.opencga.core.response.OpenCGAResult; import org.opencb.opencga.core.testclassification.duration.LongTests; import org.opencb.opencga.core.tools.result.ExecutionResult; @@ -349,12 +349,25 @@ public void testVariantSecondarySampleIndex() throws Exception { assertEquals(sample, 1, sampleIndex.getVersion().intValue()); } + try { + toolRunner.execute(VariantSecondarySampleIndexOperationTool.class, STUDY, + new VariantSecondarySampleIndexParams() + .setFamilyIndex(true) + .setSample(Arrays.asList(mother)), + Paths.get(opencga.createTmpOutdir()), "index", token); + fail("Expected to fail"); + } catch (ToolException e) { + assertEquals("Exception from step 'familyIndex'", e.getMessage()); + assertEquals("No trios found for samples [" + mother + "]", e.getCause().getMessage()); + } + // Run family index. The family index status should be READY on offspring - toolRunner.execute(VariantSecondarySampleIndexOperationTool.class, STUDY, + ExecutionResult result = toolRunner.execute(VariantSecondarySampleIndexOperationTool.class, STUDY, new VariantSecondarySampleIndexParams() .setFamilyIndex(true) .setSample(Arrays.asList(ParamConstants.ALL)), Paths.get(opencga.createTmpOutdir()), "index", token); + assertEquals(0, result.getEvents().size()); for (String sample : samples) { SampleInternalVariantSecondarySampleIndex sampleIndex = catalogManager.getSampleManager().get(STUDY, sample, new QueryOptions(), token).first().getInternal().getVariant().getSecondarySampleIndex(); diff --git a/opencga-analysis/src/test/java/org/opencb/opencga/analysis/variant/manager/operations/PlatinumFileIndexerTest.java b/opencga-analysis/src/test/java/org/opencb/opencga/analysis/variant/manager/operations/PlatinumFileIndexerTest.java index f6082bea5d2..588cf6a7846 100644 --- a/opencga-analysis/src/test/java/org/opencb/opencga/analysis/variant/manager/operations/PlatinumFileIndexerTest.java +++ b/opencga-analysis/src/test/java/org/opencb/opencga/analysis/variant/manager/operations/PlatinumFileIndexerTest.java @@ -30,8 +30,8 @@ import org.opencb.opencga.core.api.ParamConstants; import org.opencb.opencga.core.exceptions.ToolException; import org.opencb.opencga.core.models.file.File; -import org.opencb.opencga.core.models.variant.VariantFileIndexJobLauncherParams; -import org.opencb.opencga.core.models.variant.VariantIndexParams; +import org.opencb.opencga.core.models.operations.variant.VariantFileIndexJobLauncherParams; +import org.opencb.opencga.core.models.operations.variant.VariantIndexParams; import org.opencb.opencga.core.testclassification.duration.MediumTests; import org.opencb.opencga.core.tools.result.ExecutionResult; import org.opencb.opencga.storage.core.StorageEngineFactory; diff --git a/opencga-analysis/src/test/java/org/opencb/opencga/analysis/variant/manager/operations/VariantFileIndexerOperationManagerTest.java b/opencga-analysis/src/test/java/org/opencb/opencga/analysis/variant/manager/operations/VariantFileIndexerOperationManagerTest.java index 8eaddc3eba8..8151de1721b 100644 --- a/opencga-analysis/src/test/java/org/opencb/opencga/analysis/variant/manager/operations/VariantFileIndexerOperationManagerTest.java +++ b/opencga-analysis/src/test/java/org/opencb/opencga/analysis/variant/manager/operations/VariantFileIndexerOperationManagerTest.java @@ -30,7 +30,6 @@ import org.opencb.commons.datastore.core.Event; import org.opencb.commons.datastore.core.Query; import org.opencb.commons.datastore.core.QueryOptions; -import org.opencb.opencga.analysis.file.FileDeleteTask; import org.opencb.opencga.analysis.tools.ToolRunner; import org.opencb.opencga.analysis.variant.operations.VariantIndexOperationTool; import org.opencb.opencga.catalog.db.api.CohortDBAdaptor; @@ -45,9 +44,8 @@ import org.opencb.opencga.core.models.file.FileInternalVariantIndex; import org.opencb.opencga.core.models.file.VariantIndexStatus; import org.opencb.opencga.core.models.study.Study; -import org.opencb.opencga.core.models.variant.VariantIndexParams; +import org.opencb.opencga.core.models.operations.variant.VariantIndexParams; import org.opencb.opencga.core.testclassification.duration.MediumTests; -import org.opencb.opencga.core.tools.annotations.Tool; import org.opencb.opencga.core.tools.result.ExecutionResult; import org.opencb.opencga.storage.core.StorageEngineFactory; import org.opencb.opencga.storage.core.StoragePipelineResult; diff --git a/opencga-analysis/src/test/java/org/opencb/opencga/analysis/variant/manager/operations/VariantVirtualFileIndexTest.java b/opencga-analysis/src/test/java/org/opencb/opencga/analysis/variant/manager/operations/VariantVirtualFileIndexTest.java index 594e86af3dd..efa7e27fad7 100644 --- a/opencga-analysis/src/test/java/org/opencb/opencga/analysis/variant/manager/operations/VariantVirtualFileIndexTest.java +++ b/opencga-analysis/src/test/java/org/opencb/opencga/analysis/variant/manager/operations/VariantVirtualFileIndexTest.java @@ -26,7 +26,7 @@ import org.opencb.opencga.core.api.ParamConstants; import org.opencb.opencga.core.models.file.File; import org.opencb.opencga.core.models.file.FileLinkParams; -import org.opencb.opencga.core.models.variant.VariantIndexParams; +import org.opencb.opencga.core.models.operations.variant.VariantIndexParams; import org.opencb.opencga.core.testclassification.duration.MediumTests; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/opencga-app/src/main/java/org/opencb/opencga/app/cli/main/executors/AnalysisVariantCommandExecutor.java b/opencga-app/src/main/java/org/opencb/opencga/app/cli/main/executors/AnalysisVariantCommandExecutor.java index 33dfbc54a41..59d5ba0c3db 100644 --- a/opencga-app/src/main/java/org/opencb/opencga/app/cli/main/executors/AnalysisVariantCommandExecutor.java +++ b/opencga-app/src/main/java/org/opencb/opencga/app/cli/main/executors/AnalysisVariantCommandExecutor.java @@ -1,16 +1,9 @@ package org.opencb.opencga.app.cli.main.executors; import com.fasterxml.jackson.databind.DeserializationFeature; -import com.fasterxml.jackson.databind.ObjectMapper; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import org.opencb.biodata.models.clinical.ClinicalProperty.ModeOfInheritance; -import org.opencb.biodata.models.clinical.ClinicalProperty.Penetrance; import org.opencb.biodata.models.clinical.qc.Signature; import org.opencb.biodata.models.variant.Variant; import org.opencb.biodata.models.variant.avro.VariantAnnotation; -import org.opencb.biodata.models.variant.metadata.Aggregation; import org.opencb.biodata.models.variant.metadata.SampleVariantStats; import org.opencb.biodata.models.variant.metadata.VariantMetadata; import org.opencb.biodata.models.variant.metadata.VariantSetStats; @@ -19,17 +12,14 @@ import org.opencb.commons.datastore.core.QueryResponse; import org.opencb.commons.utils.PrintUtils; import org.opencb.opencga.app.cli.main.*; -import org.opencb.opencga.app.cli.main.executors.OpencgaCommandExecutor; import org.opencb.opencga.app.cli.main.options.AnalysisVariantCommandOptions; import org.opencb.opencga.catalog.exceptions.CatalogAuthenticationException; -import org.opencb.opencga.client.exceptions.ClientException; import org.opencb.opencga.core.common.JacksonUtils; import org.opencb.opencga.core.models.analysis.knockout.KnockoutByGene; import org.opencb.opencga.core.models.analysis.knockout.KnockoutByIndividual; import org.opencb.opencga.core.models.clinical.ExomiserWrapperParams; import org.opencb.opencga.core.models.job.Job; import org.opencb.opencga.core.models.operations.variant.VariantStatsExportParams; -import org.opencb.opencga.core.models.variant.AnnotationVariantQueryParams; import org.opencb.opencga.core.models.variant.CircosAnalysisParams; import org.opencb.opencga.core.models.variant.CohortVariantStatsAnalysisParams; import org.opencb.opencga.core.models.variant.FamilyQcAnalysisParams; @@ -50,11 +40,10 @@ import org.opencb.opencga.core.models.variant.SampleVariantFilterParams; import org.opencb.opencga.core.models.variant.SampleVariantStatsAnalysisParams; import org.opencb.opencga.core.models.variant.VariantExportParams; -import org.opencb.opencga.core.models.variant.VariantIndexParams; +import org.opencb.opencga.core.models.operations.variant.VariantIndexParams; import org.opencb.opencga.core.models.variant.VariantStatsAnalysisParams; import org.opencb.opencga.core.response.QueryType; import org.opencb.opencga.core.response.RestResponse; -import org.opencb.oskar.analysis.variant.gwas.GwasConfiguration; /* diff --git a/opencga-app/src/main/java/org/opencb/opencga/app/cli/main/executors/OperationsVariantStorageCommandExecutor.java b/opencga-app/src/main/java/org/opencb/opencga/app/cli/main/executors/OperationsVariantStorageCommandExecutor.java index 068b4a3792a..294763c0b74 100644 --- a/opencga-app/src/main/java/org/opencb/opencga/app/cli/main/executors/OperationsVariantStorageCommandExecutor.java +++ b/opencga-app/src/main/java/org/opencb/opencga/app/cli/main/executors/OperationsVariantStorageCommandExecutor.java @@ -1,19 +1,12 @@ package org.opencb.opencga.app.cli.main.executors; import com.fasterxml.jackson.databind.DeserializationFeature; -import com.fasterxml.jackson.databind.ObjectMapper; -import java.util.HashMap; -import java.util.List; -import org.opencb.biodata.models.variant.metadata.Aggregation; import org.opencb.commons.datastore.core.ObjectMap; import org.opencb.commons.utils.PrintUtils; import org.opencb.opencga.app.cli.main.*; -import org.opencb.opencga.app.cli.main.executors.OpencgaCommandExecutor; import org.opencb.opencga.app.cli.main.options.OperationsVariantStorageCommandOptions; import org.opencb.opencga.catalog.exceptions.CatalogAuthenticationException; -import org.opencb.opencga.client.exceptions.ClientException; import org.opencb.opencga.core.common.JacksonUtils; -import org.opencb.opencga.core.common.YesNoAuto; import org.opencb.opencga.core.config.storage.CellBaseConfiguration; import org.opencb.opencga.core.config.storage.SampleIndexConfiguration; import org.opencb.opencga.core.models.job.Job; @@ -29,14 +22,14 @@ import org.opencb.opencga.core.models.operations.variant.VariantStatsDeleteParams; import org.opencb.opencga.core.models.operations.variant.VariantStatsIndexParams; import org.opencb.opencga.core.models.operations.variant.VariantStorageMetadataRepairToolParams; -import org.opencb.opencga.core.models.variant.VariantConfigureParams; -import org.opencb.opencga.core.models.variant.VariantFileDeleteParams; -import org.opencb.opencga.core.models.variant.VariantFileIndexJobLauncherParams; -import org.opencb.opencga.core.models.variant.VariantIndexParams; -import org.opencb.opencga.core.models.variant.VariantPruneParams; -import org.opencb.opencga.core.models.variant.VariantSampleDeleteParams; -import org.opencb.opencga.core.models.variant.VariantStorageMetadataSynchronizeParams; -import org.opencb.opencga.core.models.variant.VariantStudyDeleteParams; +import org.opencb.opencga.core.models.operations.variant.VariantConfigureParams; +import org.opencb.opencga.core.models.operations.variant.VariantFileDeleteParams; +import org.opencb.opencga.core.models.operations.variant.VariantFileIndexJobLauncherParams; +import org.opencb.opencga.core.models.operations.variant.VariantIndexParams; +import org.opencb.opencga.core.models.operations.variant.VariantPruneParams; +import org.opencb.opencga.core.models.operations.variant.VariantSampleDeleteParams; +import org.opencb.opencga.core.models.operations.variant.VariantStorageMetadataSynchronizeParams; +import org.opencb.opencga.core.models.operations.variant.VariantStudyDeleteParams; import org.opencb.opencga.core.response.QueryType; import org.opencb.opencga.core.response.RestResponse; diff --git a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/managers/JobManager.java b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/managers/JobManager.java index a084a6bfb82..96664425beb 100644 --- a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/managers/JobManager.java +++ b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/managers/JobManager.java @@ -40,6 +40,7 @@ import org.opencb.opencga.core.api.ParamConstants; import org.opencb.opencga.core.common.TimeUtils; import org.opencb.opencga.core.config.Configuration; +import org.opencb.opencga.core.config.Execution; import org.opencb.opencga.core.models.AclEntryList; import org.opencb.opencga.core.models.AclParams; import org.opencb.opencga.core.models.audit.AuditRecord; @@ -595,7 +596,7 @@ private OpenCGAResult getJobToReuse(Study study, String inputJobId, Job job private boolean jobEligibleToReuse(String inputJobId, Job job) { boolean enabled = configuration.getAnalysis().getExecution().getOptions() - .getBoolean("jobs.reuse.enabled", true); + .getBoolean(Execution.JOBS_REUSE_ENABLED, Execution.JOBS_REUSE_ENABLED_DEFAULT); if (!enabled) { return false; } @@ -606,9 +607,9 @@ private boolean jobEligibleToReuse(String inputJobId, Job job) { } List availableTools = configuration.getAnalysis().getExecution().getOptions() - .getAsStringList("jobs.reuse.tools"); + .getAsStringList(Execution.JOBS_REUSE_TOOLS); if (availableTools.isEmpty()) { - availableTools = Collections.singletonList("variant-.*"); + availableTools = Execution.JOBS_REUSE_TOOLS_DEFAULT; } String toolId = job.getTool().getId(); boolean validTool = false; diff --git a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/VariantClient.java b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/VariantClient.java index c7f91a4730a..1480df3ca9e 100644 --- a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/VariantClient.java +++ b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/VariantClient.java @@ -53,7 +53,7 @@ import org.opencb.opencga.core.models.variant.SampleVariantFilterParams; import org.opencb.opencga.core.models.variant.SampleVariantStatsAnalysisParams; import org.opencb.opencga.core.models.variant.VariantExportParams; -import org.opencb.opencga.core.models.variant.VariantIndexParams; +import org.opencb.opencga.core.models.operations.variant.VariantIndexParams; import org.opencb.opencga.core.models.variant.VariantStatsAnalysisParams; import org.opencb.opencga.core.response.RestResponse; diff --git a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/VariantOperationClient.java b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/VariantOperationClient.java index 92f5dd6772d..5351b58c869 100644 --- a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/VariantOperationClient.java +++ b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/VariantOperationClient.java @@ -35,14 +35,14 @@ import org.opencb.opencga.core.models.operations.variant.VariantStatsDeleteParams; import org.opencb.opencga.core.models.operations.variant.VariantStatsIndexParams; import org.opencb.opencga.core.models.operations.variant.VariantStorageMetadataRepairToolParams; -import org.opencb.opencga.core.models.variant.VariantConfigureParams; -import org.opencb.opencga.core.models.variant.VariantFileDeleteParams; -import org.opencb.opencga.core.models.variant.VariantFileIndexJobLauncherParams; -import org.opencb.opencga.core.models.variant.VariantIndexParams; -import org.opencb.opencga.core.models.variant.VariantPruneParams; -import org.opencb.opencga.core.models.variant.VariantSampleDeleteParams; -import org.opencb.opencga.core.models.variant.VariantStorageMetadataSynchronizeParams; -import org.opencb.opencga.core.models.variant.VariantStudyDeleteParams; +import org.opencb.opencga.core.models.operations.variant.VariantConfigureParams; +import org.opencb.opencga.core.models.operations.variant.VariantFileDeleteParams; +import org.opencb.opencga.core.models.operations.variant.VariantFileIndexJobLauncherParams; +import org.opencb.opencga.core.models.operations.variant.VariantIndexParams; +import org.opencb.opencga.core.models.operations.variant.VariantPruneParams; +import org.opencb.opencga.core.models.operations.variant.VariantSampleDeleteParams; +import org.opencb.opencga.core.models.operations.variant.VariantStorageMetadataSynchronizeParams; +import org.opencb.opencga.core.models.operations.variant.VariantStudyDeleteParams; import org.opencb.opencga.core.response.RestResponse; diff --git a/opencga-core/src/main/java/org/opencb/opencga/core/api/ParamConstants.java b/opencga-core/src/main/java/org/opencb/opencga/core/api/ParamConstants.java index b1cb9911e9a..ba0afa4dfc6 100644 --- a/opencga-core/src/main/java/org/opencb/opencga/core/api/ParamConstants.java +++ b/opencga-core/src/main/java/org/opencb/opencga/core/api/ParamConstants.java @@ -87,6 +87,8 @@ public class ParamConstants { public static final String OPENCGA_TOKEN_CLI_PARAM = "--opencga-token"; + public static final String RESUME_DESCRIPTION = "Resume a previously failed index operation"; + // --------------------------------------------- public static final String FORCE = "force"; public static final String ANNOTATION_DOC_URL = "http://docs.opencb.org/display/opencga/AnnotationSets+1.4.0"; diff --git a/opencga-core/src/main/java/org/opencb/opencga/core/config/Execution.java b/opencga-core/src/main/java/org/opencb/opencga/core/config/Execution.java index 2bc200fe8fb..1384d0a7df1 100644 --- a/opencga-core/src/main/java/org/opencb/opencga/core/config/Execution.java +++ b/opencga-core/src/main/java/org/opencb/opencga/core/config/Execution.java @@ -18,6 +18,7 @@ import org.opencb.commons.datastore.core.ObjectMap; +import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -27,6 +28,16 @@ */ public class Execution { + public static final String JOBS_REUSE_ENABLED = "jobs.reuse.enabled"; + public static final boolean JOBS_REUSE_ENABLED_DEFAULT = true; + public static final String JOBS_REUSE_TOOLS = "jobs.reuse.tools"; + public static final List JOBS_REUSE_TOOLS_DEFAULT = Arrays.asList( + "variant-index", + "variant-stats-index", + "variant-annotation-index", + "variant-secondary-annotation-index", + "variant-secondary-sample-index" + ); private String id; private String defaultQueue; private String availableQueues; diff --git a/opencga-core/src/main/java/org/opencb/opencga/core/models/operations/variant/VariantAggregateFamilyParams.java b/opencga-core/src/main/java/org/opencb/opencga/core/models/operations/variant/VariantAggregateFamilyParams.java index 42b9073b45d..5f73c45e964 100644 --- a/opencga-core/src/main/java/org/opencb/opencga/core/models/operations/variant/VariantAggregateFamilyParams.java +++ b/opencga-core/src/main/java/org/opencb/opencga/core/models/operations/variant/VariantAggregateFamilyParams.java @@ -16,14 +16,20 @@ package org.opencb.opencga.core.models.operations.variant; +import org.opencb.commons.annotations.DataField; +import org.opencb.opencga.core.api.ParamConstants; import org.opencb.opencga.core.tools.ToolParams; import java.util.List; public class VariantAggregateFamilyParams extends ToolParams { public static final String DESCRIPTION = "Variant aggregate family params."; + + @DataField(description = "Samples within the same study to aggregate") private List samples; + @DataField(description = "Genotype to be used in gaps. Either 0/0, ./. or ?/?") private String gapsGenotype; + @DataField(description = ParamConstants.RESUME_DESCRIPTION) private boolean resume; public VariantAggregateFamilyParams() { diff --git a/opencga-core/src/main/java/org/opencb/opencga/core/models/operations/variant/VariantAggregateParams.java b/opencga-core/src/main/java/org/opencb/opencga/core/models/operations/variant/VariantAggregateParams.java index 87880318218..434643acc33 100644 --- a/opencga-core/src/main/java/org/opencb/opencga/core/models/operations/variant/VariantAggregateParams.java +++ b/opencga-core/src/main/java/org/opencb/opencga/core/models/operations/variant/VariantAggregateParams.java @@ -16,13 +16,17 @@ package org.opencb.opencga.core.models.operations.variant; +import org.opencb.commons.annotations.DataField; +import org.opencb.opencga.core.api.ParamConstants; import org.opencb.opencga.core.tools.ToolParams; public class VariantAggregateParams extends ToolParams { public static final String DESCRIPTION = "Variant aggregate params."; - // private String region; + // private String region + @DataField(description = "Overwrite aggregation for all files and variants. Repeat operation for already processed variants.") private boolean overwrite; + @DataField(description = ParamConstants.RESUME_DESCRIPTION) private boolean resume; public VariantAggregateParams() { diff --git a/opencga-core/src/main/java/org/opencb/opencga/core/models/operations/variant/VariantAnnotationDeleteParams.java b/opencga-core/src/main/java/org/opencb/opencga/core/models/operations/variant/VariantAnnotationDeleteParams.java index bb1072e5f98..797ee2cbdf5 100644 --- a/opencga-core/src/main/java/org/opencb/opencga/core/models/operations/variant/VariantAnnotationDeleteParams.java +++ b/opencga-core/src/main/java/org/opencb/opencga/core/models/operations/variant/VariantAnnotationDeleteParams.java @@ -16,10 +16,12 @@ package org.opencb.opencga.core.models.operations.variant; +import org.opencb.commons.annotations.DataField; import org.opencb.opencga.core.tools.ToolParams; public class VariantAnnotationDeleteParams extends ToolParams { + @DataField(description = "Variant Annotation identifier") private String annotationId; public VariantAnnotationDeleteParams() { diff --git a/opencga-core/src/main/java/org/opencb/opencga/core/models/operations/variant/VariantAnnotationSaveParams.java b/opencga-core/src/main/java/org/opencb/opencga/core/models/operations/variant/VariantAnnotationSaveParams.java index 373261ea395..948f3a453c0 100644 --- a/opencga-core/src/main/java/org/opencb/opencga/core/models/operations/variant/VariantAnnotationSaveParams.java +++ b/opencga-core/src/main/java/org/opencb/opencga/core/models/operations/variant/VariantAnnotationSaveParams.java @@ -16,11 +16,13 @@ package org.opencb.opencga.core.models.operations.variant; +import org.opencb.commons.annotations.DataField; import org.opencb.opencga.core.tools.ToolParams; public class VariantAnnotationSaveParams extends ToolParams { public static final String DESCRIPTION = "Variant annotation save params"; + @DataField(description = "New Variant Annotation identifier") private String annotationId; public VariantAnnotationSaveParams() { diff --git a/opencga-core/src/main/java/org/opencb/opencga/core/models/variant/VariantConfigureParams.java b/opencga-core/src/main/java/org/opencb/opencga/core/models/operations/variant/VariantConfigureParams.java similarity index 85% rename from opencga-core/src/main/java/org/opencb/opencga/core/models/variant/VariantConfigureParams.java rename to opencga-core/src/main/java/org/opencb/opencga/core/models/operations/variant/VariantConfigureParams.java index 3365908a43f..51a22f36337 100644 --- a/opencga-core/src/main/java/org/opencb/opencga/core/models/variant/VariantConfigureParams.java +++ b/opencga-core/src/main/java/org/opencb/opencga/core/models/operations/variant/VariantConfigureParams.java @@ -1,4 +1,4 @@ -package org.opencb.opencga.core.models.variant; +package org.opencb.opencga.core.models.operations.variant; import org.opencb.commons.datastore.core.ObjectMap; diff --git a/opencga-core/src/main/java/org/opencb/opencga/core/models/operations/variant/VariantFamilyIndexParams.java b/opencga-core/src/main/java/org/opencb/opencga/core/models/operations/variant/VariantFamilyIndexParams.java index 0a2c8d3b8b5..23f89c9bbd0 100644 --- a/opencga-core/src/main/java/org/opencb/opencga/core/models/operations/variant/VariantFamilyIndexParams.java +++ b/opencga-core/src/main/java/org/opencb/opencga/core/models/operations/variant/VariantFamilyIndexParams.java @@ -20,6 +20,7 @@ import java.util.List; +@Deprecated public class VariantFamilyIndexParams extends ToolParams { public static final String DESCRIPTION = "Variant family index params."; diff --git a/opencga-core/src/main/java/org/opencb/opencga/core/models/variant/VariantFileDeleteParams.java b/opencga-core/src/main/java/org/opencb/opencga/core/models/operations/variant/VariantFileDeleteParams.java similarity index 95% rename from opencga-core/src/main/java/org/opencb/opencga/core/models/variant/VariantFileDeleteParams.java rename to opencga-core/src/main/java/org/opencb/opencga/core/models/operations/variant/VariantFileDeleteParams.java index 82a1daa3670..1a44f224af7 100644 --- a/opencga-core/src/main/java/org/opencb/opencga/core/models/variant/VariantFileDeleteParams.java +++ b/opencga-core/src/main/java/org/opencb/opencga/core/models/operations/variant/VariantFileDeleteParams.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.opencb.opencga.core.models.variant; +package org.opencb.opencga.core.models.operations.variant; import org.opencb.opencga.core.tools.ToolParams; diff --git a/opencga-core/src/main/java/org/opencb/opencga/core/models/variant/VariantFileIndexJobLauncherParams.java b/opencga-core/src/main/java/org/opencb/opencga/core/models/operations/variant/VariantFileIndexJobLauncherParams.java similarity index 97% rename from opencga-core/src/main/java/org/opencb/opencga/core/models/variant/VariantFileIndexJobLauncherParams.java rename to opencga-core/src/main/java/org/opencb/opencga/core/models/operations/variant/VariantFileIndexJobLauncherParams.java index 75404921751..28f3dbc8ff1 100644 --- a/opencga-core/src/main/java/org/opencb/opencga/core/models/variant/VariantFileIndexJobLauncherParams.java +++ b/opencga-core/src/main/java/org/opencb/opencga/core/models/operations/variant/VariantFileIndexJobLauncherParams.java @@ -1,4 +1,4 @@ -package org.opencb.opencga.core.models.variant; +package org.opencb.opencga.core.models.operations.variant; import org.opencb.opencga.core.tools.ToolParams; diff --git a/opencga-core/src/main/java/org/opencb/opencga/core/models/variant/VariantIndexParams.java b/opencga-core/src/main/java/org/opencb/opencga/core/models/operations/variant/VariantIndexParams.java similarity index 98% rename from opencga-core/src/main/java/org/opencb/opencga/core/models/variant/VariantIndexParams.java rename to opencga-core/src/main/java/org/opencb/opencga/core/models/operations/variant/VariantIndexParams.java index 1e0cd7dac49..505327de602 100644 --- a/opencga-core/src/main/java/org/opencb/opencga/core/models/variant/VariantIndexParams.java +++ b/opencga-core/src/main/java/org/opencb/opencga/core/models/operations/variant/VariantIndexParams.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.opencb.opencga.core.models.variant; +package org.opencb.opencga.core.models.operations.variant; import org.opencb.biodata.models.variant.metadata.Aggregation; import org.opencb.commons.annotations.DataField; @@ -81,7 +81,7 @@ public VariantIndexParams(String file, @DataField(description = "List of files to be indexed.") private String file; - @DataField(description = "Resume a previously failed index operation") + @DataField(description = ParamConstants.RESUME_DESCRIPTION) private boolean resume; @DataField(description = "Output directory") private String outdir; @@ -101,7 +101,7 @@ public VariantIndexParams(String file, private String failOnMalformedLines; @DataField(description = "Indicate that the files to be loaded are part of a family. " - + "This will set 'load-hom-ref' to YES if it was in AUTO and execute 'family-index' afterwards") + + "This will set 'load-hom-ref' to YES if it was in AUTO") private boolean family; @DataField(description = "Indicate that the files to be loaded contain somatic samples. " + "This will set 'load-hom-ref' to YES if it was in AUTO.") diff --git a/opencga-core/src/main/java/org/opencb/opencga/core/models/variant/VariantPruneParams.java b/opencga-core/src/main/java/org/opencb/opencga/core/models/operations/variant/VariantPruneParams.java similarity index 93% rename from opencga-core/src/main/java/org/opencb/opencga/core/models/variant/VariantPruneParams.java rename to opencga-core/src/main/java/org/opencb/opencga/core/models/operations/variant/VariantPruneParams.java index ed0449871e6..d59ead10217 100644 --- a/opencga-core/src/main/java/org/opencb/opencga/core/models/variant/VariantPruneParams.java +++ b/opencga-core/src/main/java/org/opencb/opencga/core/models/operations/variant/VariantPruneParams.java @@ -1,4 +1,4 @@ -package org.opencb.opencga.core.models.variant; +package org.opencb.opencga.core.models.operations.variant; import org.opencb.opencga.core.tools.ToolParams; diff --git a/opencga-core/src/main/java/org/opencb/opencga/core/models/variant/VariantSampleDeleteParams.java b/opencga-core/src/main/java/org/opencb/opencga/core/models/operations/variant/VariantSampleDeleteParams.java similarity index 96% rename from opencga-core/src/main/java/org/opencb/opencga/core/models/variant/VariantSampleDeleteParams.java rename to opencga-core/src/main/java/org/opencb/opencga/core/models/operations/variant/VariantSampleDeleteParams.java index 4857a35a650..3ae43e6b61f 100644 --- a/opencga-core/src/main/java/org/opencb/opencga/core/models/variant/VariantSampleDeleteParams.java +++ b/opencga-core/src/main/java/org/opencb/opencga/core/models/operations/variant/VariantSampleDeleteParams.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.opencb.opencga.core.models.variant; +package org.opencb.opencga.core.models.operations.variant; import org.opencb.opencga.core.tools.ToolParams; diff --git a/opencga-core/src/main/java/org/opencb/opencga/core/models/variant/VariantStorageMetadataSynchronizeParams.java b/opencga-core/src/main/java/org/opencb/opencga/core/models/operations/variant/VariantStorageMetadataSynchronizeParams.java similarity index 92% rename from opencga-core/src/main/java/org/opencb/opencga/core/models/variant/VariantStorageMetadataSynchronizeParams.java rename to opencga-core/src/main/java/org/opencb/opencga/core/models/operations/variant/VariantStorageMetadataSynchronizeParams.java index f5a2b25f11d..002bff2f937 100644 --- a/opencga-core/src/main/java/org/opencb/opencga/core/models/variant/VariantStorageMetadataSynchronizeParams.java +++ b/opencga-core/src/main/java/org/opencb/opencga/core/models/operations/variant/VariantStorageMetadataSynchronizeParams.java @@ -1,4 +1,4 @@ -package org.opencb.opencga.core.models.variant; +package org.opencb.opencga.core.models.operations.variant; import org.opencb.opencga.core.tools.ToolParams; diff --git a/opencga-core/src/main/java/org/opencb/opencga/core/models/variant/VariantStudyDeleteParams.java b/opencga-core/src/main/java/org/opencb/opencga/core/models/operations/variant/VariantStudyDeleteParams.java similarity index 95% rename from opencga-core/src/main/java/org/opencb/opencga/core/models/variant/VariantStudyDeleteParams.java rename to opencga-core/src/main/java/org/opencb/opencga/core/models/operations/variant/VariantStudyDeleteParams.java index 20f533e711a..1922fe78bf0 100644 --- a/opencga-core/src/main/java/org/opencb/opencga/core/models/variant/VariantStudyDeleteParams.java +++ b/opencga-core/src/main/java/org/opencb/opencga/core/models/operations/variant/VariantStudyDeleteParams.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.opencb.opencga.core.models.variant; +package org.opencb.opencga.core.models.operations.variant; import org.opencb.opencga.core.tools.ToolParams; diff --git a/opencga-core/src/main/resources/configuration.yml b/opencga-core/src/main/resources/configuration.yml index ff81c0b196c..dfc1526ab57 100644 --- a/opencga-core/src/main/resources/configuration.yml +++ b/opencga-core/src/main/resources/configuration.yml @@ -138,7 +138,8 @@ analysis: maxConcurrentJobs: variant-index: 20 variant-annotation-index: 5 - variant-secondary-index: 2 + variant-secondary-annotation-index: 2 + variant-secondary-sample-index: 2 options: ## Job reuse policy. Do not create a new job if an equivalent PENDING or QUEUED job exists. jobs.reuse.enabled: true @@ -148,6 +149,7 @@ analysis: - "variant-stats-index" - "variant-annotation-index" - "variant-secondary-annotation-index" + - "variant-secondary-sample-index" ## Local executor configuration local.maxConcurrentJobs: 2 # Max number of concurrent jobs to be executed locally in the master ## Azure Batch Service configuration example diff --git a/opencga-server/src/main/java/org/opencb/opencga/server/rest/analysis/VariantWebService.java b/opencga-server/src/main/java/org/opencb/opencga/server/rest/analysis/VariantWebService.java index e8ca41e1283..7885e38080b 100644 --- a/opencga-server/src/main/java/org/opencb/opencga/server/rest/analysis/VariantWebService.java +++ b/opencga-server/src/main/java/org/opencb/opencga/server/rest/analysis/VariantWebService.java @@ -16,7 +16,6 @@ package org.opencb.opencga.server.rest.analysis; -import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.io.FileUtils; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.time.StopWatch; @@ -27,14 +26,9 @@ import org.opencb.biodata.models.variant.metadata.SampleVariantStats; import org.opencb.biodata.models.variant.metadata.VariantMetadata; import org.opencb.biodata.models.variant.metadata.VariantSetStats; -import org.opencb.commons.annotations.DataField; import org.opencb.commons.datastore.core.*; -import org.opencb.opencga.analysis.AnalysisUtils; -import org.opencb.opencga.analysis.ResourceUtils; -import org.opencb.opencga.analysis.alignment.AlignmentConstants; import org.opencb.opencga.analysis.family.qc.FamilyQcAnalysis; import org.opencb.opencga.analysis.individual.qc.IndividualQcAnalysis; -import org.opencb.opencga.analysis.individual.qc.IndividualQcUtils; import org.opencb.opencga.analysis.sample.qc.SampleQcAnalysis; import org.opencb.opencga.analysis.variant.VariantExportTool; import org.opencb.opencga.analysis.variant.circos.CircosAnalysis; @@ -57,13 +51,10 @@ import org.opencb.opencga.analysis.variant.stats.CohortVariantStatsAnalysis; import org.opencb.opencga.analysis.variant.stats.SampleVariantStatsAnalysis; import org.opencb.opencga.analysis.variant.stats.VariantStatsAnalysis; -import org.opencb.opencga.analysis.wrappers.deeptools.DeeptoolsWrapperAnalysis; import org.opencb.opencga.analysis.wrappers.exomiser.ExomiserWrapperAnalysis; import org.opencb.opencga.analysis.wrappers.gatk.GatkWrapperAnalysis; import org.opencb.opencga.analysis.wrappers.plink.PlinkWrapperAnalysis; import org.opencb.opencga.analysis.wrappers.rvtests.RvtestsWrapperAnalysis; -import org.opencb.opencga.analysis.wrappers.samtools.SamtoolsWrapperAnalysis; -import org.opencb.opencga.catalog.db.api.FileDBAdaptor; import org.opencb.opencga.catalog.exceptions.CatalogException; import org.opencb.opencga.catalog.utils.AvroToAnnotationConverter; import org.opencb.opencga.catalog.utils.ParamUtils; @@ -73,15 +64,14 @@ import org.opencb.opencga.core.common.TimeUtils; import org.opencb.opencga.core.exceptions.ToolException; import org.opencb.opencga.core.exceptions.VersionException; -import org.opencb.opencga.core.models.alignment.DeeptoolsWrapperParams; -import org.opencb.opencga.core.models.alignment.SamtoolsWrapperParams; import org.opencb.opencga.core.models.analysis.knockout.KnockoutByGene; import org.opencb.opencga.core.models.analysis.knockout.KnockoutByIndividual; import org.opencb.opencga.core.models.clinical.ExomiserWrapperParams; import org.opencb.opencga.core.models.cohort.Cohort; import org.opencb.opencga.core.models.common.AnnotationSet; -import org.opencb.opencga.core.models.individual.Individual; import org.opencb.opencga.core.models.job.Job; +import org.opencb.opencga.core.models.operations.variant.VariantFileDeleteParams; +import org.opencb.opencga.core.models.operations.variant.VariantIndexParams; import org.opencb.opencga.core.models.operations.variant.VariantStatsExportParams; import org.opencb.opencga.core.models.sample.Sample; import org.opencb.opencga.core.models.variant.*; From 41fb753bbee38f65126061cfbc36dd82d9de76c1 Mon Sep 17 00:00:00 2001 From: pfurio Date: Wed, 28 Feb 2024 11:27:46 +0100 Subject: [PATCH 03/85] catalog: calls to updates are always sent to the DBAdaptors, #TASK-5668 --- .../db/api/AnnotationSetDBAdaptor.java | 20 +- .../opencga/catalog/db/api/DBAdaptor.java | 15 - .../catalog/db/api/ProjectDBAdaptor.java | 11 - .../catalog/db/api/StudyDBAdaptor.java | 19 +- .../db/mongodb/AnnotationMongoDBAdaptor.java | 310 ++++++++--------- .../db/mongodb/CatalogMongoDBAdaptor.java | 35 ++ .../ClinicalAnalysisMongoDBAdaptor.java | 51 ++- .../db/mongodb/CohortMongoDBAdaptor.java | 28 +- .../db/mongodb/FamilyMongoDBAdaptor.java | 94 +++-- .../db/mongodb/FileMongoDBAdaptor.java | 85 +++-- .../db/mongodb/IndividualMongoDBAdaptor.java | 324 ++++++++++++------ .../mongodb/InterpretationMongoDBAdaptor.java | 12 +- .../catalog/db/mongodb/JobMongoDBAdaptor.java | 2 +- .../catalog/db/mongodb/MongoDBAdaptor.java | 2 +- .../db/mongodb/PanelMongoDBAdaptor.java | 6 +- .../db/mongodb/ProjectMongoDBAdaptor.java | 4 +- .../db/mongodb/SampleMongoDBAdaptor.java | 190 +++++++--- .../db/mongodb/StudyMongoDBAdaptor.java | 34 +- .../db/mongodb/UserMongoDBAdaptor.java | 2 +- .../db/mongodb/VersionedMongoDBAdaptor.java | 49 ++- .../mongodb/converters/SampleConverter.java | 1 - .../opencga/catalog/managers/FileManager.java | 2 +- .../catalog/managers/StudyManager.java | 4 +- .../db/mongodb/StudyMongoDBAdaptorTest.java | 14 +- 24 files changed, 822 insertions(+), 492 deletions(-) create mode 100644 opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/CatalogMongoDBAdaptor.java diff --git a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/api/AnnotationSetDBAdaptor.java b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/api/AnnotationSetDBAdaptor.java index e52ca8a9f84..a06f3762b4d 100644 --- a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/api/AnnotationSetDBAdaptor.java +++ b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/api/AnnotationSetDBAdaptor.java @@ -58,12 +58,16 @@ OpenCGAResult update(Query query, ObjectMap parameters, List variab /** * Add the variable to all the possible annotations from the variableSetId using the default value. * + * @param studyUid Study uid. * @param variableSetId variable set id to identify the annotations that will add a new annotation. - * @param variable new variable that will be added. + * @param variable new variable that will be added. * @return a OpenCGAResult object. * @throws CatalogDBException if the variable could not be added to an existing annotationSet. + * @throws CatalogParameterException if there is any unexpected parameter. + * @throws CatalogAuthorizationException if the operation is not authorized. */ - OpenCGAResult addVariableToAnnotations(long variableSetId, Variable variable) throws CatalogDBException; + OpenCGAResult addVariableToAnnotations(long studyUid, long variableSetId, Variable variable) + throws CatalogDBException, CatalogParameterException, CatalogAuthorizationException; // /** // * This method will rename the id of all the annotations corresponding to the variableSetId changing oldName per newName. @@ -80,21 +84,25 @@ OpenCGAResult update(Query query, ObjectMap parameters, List variab /** * Remove the annotation with annotationName from the annotation set. * - * @param variableSetId variable set id for which the annotationSets have to delete the annotation. + * @param studyUid Study uid. + * @param variableSetId variable set id for which the annotationSets have to delete the annotation. * @param annotationName Annotation name. * @return a OpenCGAResult object. * @throws CatalogDBException when there is an error in the database. + * @throws CatalogParameterException if there is any unexpected parameter. + * @throws CatalogAuthorizationException if the operation is not authorized. */ - OpenCGAResult removeAnnotationField(long variableSetId, String annotationName) throws CatalogDBException; + OpenCGAResult removeAnnotationField(long studyUid, long variableSetId, String annotationName) + throws CatalogDBException, CatalogParameterException, CatalogAuthorizationException; /** * Makes a groupBy to obtain the different values that every annotation has and the total number of each. * * - * @param studyId study id. + * @param studyUid study uid. * @param variableSetId variable set id for which the group by will be done. * @return a list of Feature count with every different value. * @throws CatalogDBException when there is an error in the database. */ - OpenCGAResult getAnnotationSummary(long studyId, long variableSetId) throws CatalogDBException; + OpenCGAResult getAnnotationSummary(long studyUid, long variableSetId) throws CatalogDBException; } diff --git a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/api/DBAdaptor.java b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/api/DBAdaptor.java index 2b0347446ea..cd410a5dcbd 100644 --- a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/api/DBAdaptor.java +++ b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/api/DBAdaptor.java @@ -25,9 +25,7 @@ import org.opencb.opencga.catalog.exceptions.CatalogParameterException; import org.opencb.opencga.core.response.OpenCGAResult; -import java.util.ArrayList; import java.util.List; -import java.util.Objects; import java.util.function.Consumer; /** @@ -61,19 +59,6 @@ default OpenCGAResult stats() { OpenCGAResult get(Query query, QueryOptions options) throws CatalogDBException, CatalogParameterException, CatalogAuthorizationException; - OpenCGAResult nativeGet(Query query, QueryOptions options) - throws CatalogDBException, CatalogParameterException, CatalogAuthorizationException; - - default List nativeGet(List queries, QueryOptions options) - throws CatalogDBException, CatalogParameterException, CatalogAuthorizationException { - Objects.requireNonNull(queries); - List queryResults = new ArrayList<>(queries.size()); - for (Query query : queries) { - queryResults.add(nativeGet(query, options)); - } - return queryResults; - } - OpenCGAResult update(long id, ObjectMap parameters, QueryOptions queryOptions) throws CatalogDBException, CatalogParameterException, CatalogAuthorizationException; diff --git a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/api/ProjectDBAdaptor.java b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/api/ProjectDBAdaptor.java index ac605873666..e41e9029160 100644 --- a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/api/ProjectDBAdaptor.java +++ b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/api/ProjectDBAdaptor.java @@ -186,20 +186,9 @@ default List> get(List queries, QueryOptions optio return queryResults; } - OpenCGAResult nativeGet(Query query, QueryOptions options) throws CatalogDBException; - OpenCGAResult nativeGet(Query query, QueryOptions options, String user) throws CatalogDBException, CatalogAuthorizationException; - default List nativeGet(List queries, QueryOptions options) throws CatalogDBException { - Objects.requireNonNull(queries); - List queryResults = new ArrayList<>(queries.size()); - for (Query query : queries) { - queryResults.add(nativeGet(query, options)); - } - return queryResults; - } - OpenCGAResult update(long id, ObjectMap parameters, QueryOptions queryOptions) throws CatalogDBException, CatalogParameterException, CatalogAuthorizationException; diff --git a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/api/StudyDBAdaptor.java b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/api/StudyDBAdaptor.java index f74d1a843b7..7ac9ad282ff 100644 --- a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/api/StudyDBAdaptor.java +++ b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/api/StudyDBAdaptor.java @@ -82,20 +82,9 @@ default List> get(List queries, QueryOptions options return queryResults; } - OpenCGAResult nativeGet(Query query, QueryOptions options) throws CatalogDBException; - OpenCGAResult nativeGet(Query query, QueryOptions options, String user) throws CatalogDBException, CatalogAuthorizationException; - default List nativeGet(List queries, QueryOptions options) throws CatalogDBException { - Objects.requireNonNull(queries); - List queryResults = new ArrayList<>(queries.size()); - for (Query query : queries) { - queryResults.add(nativeGet(query, options)); - } - return queryResults; - } - OpenCGAResult update(long id, ObjectMap parameters, QueryOptions queryOptions) throws CatalogDBException, CatalogParameterException, CatalogAuthorizationException; @@ -395,14 +384,14 @@ default void checkVariableSetExists(String variableSetId, long studyId) throws C OpenCGAResult createVariableSet(long studyId, VariableSet variableSet) throws CatalogDBException; - OpenCGAResult addFieldToVariableSet(long variableSetId, Variable variable, String user) - throws CatalogDBException, CatalogAuthorizationException; + OpenCGAResult addFieldToVariableSet(long studyUid, long variableSetId, Variable variable, String user) + throws CatalogDBException, CatalogAuthorizationException, CatalogParameterException; OpenCGAResult renameFieldVariableSet(long variableSetId, String oldName, String newName, String user) throws CatalogDBException, CatalogAuthorizationException; - OpenCGAResult removeFieldFromVariableSet(long variableSetId, String name, String user) - throws CatalogDBException, CatalogAuthorizationException; + OpenCGAResult removeFieldFromVariableSet(long studyUid, long variableSetId, String name, String user) + throws CatalogDBException, CatalogAuthorizationException, CatalogParameterException; OpenCGAResult getVariableSet(long variableSetUid, QueryOptions options) throws CatalogDBException; diff --git a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/AnnotationMongoDBAdaptor.java b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/AnnotationMongoDBAdaptor.java index e8cfa1d0ad1..d1e48be9331 100644 --- a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/AnnotationMongoDBAdaptor.java +++ b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/AnnotationMongoDBAdaptor.java @@ -20,7 +20,6 @@ import com.mongodb.client.model.Aggregates; import com.mongodb.client.model.Filters; import com.mongodb.client.model.Projections; -import com.mongodb.client.model.Updates; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.collections4.map.LinkedMap; import org.apache.commons.lang3.StringUtils; @@ -59,7 +58,7 @@ /** * Created by pfurio on 07/07/16. */ -public abstract class AnnotationMongoDBAdaptor extends MongoDBAdaptor implements AnnotationSetDBAdaptor { +public abstract class AnnotationMongoDBAdaptor extends CatalogMongoDBAdaptor implements AnnotationSetDBAdaptor { private final AnnotationConverter annotationConverter; @@ -70,6 +69,13 @@ public abstract class AnnotationMongoDBAdaptor extends MongoDBAdaptor impleme protected abstract MongoDBCollection getCollection(); + abstract OpenCGAResult transactionalUpdate(ClientSession clientSession, T entry, ObjectMap parameters, + List variableSetList, QueryOptions queryOptions) + throws CatalogParameterException, CatalogDBException, CatalogAuthorizationException; + + abstract OpenCGAResult transactionalUpdate(ClientSession clientSession, long studyUid, Bson query, UpdateDocument updateDocument) + throws CatalogParameterException, CatalogDBException, CatalogAuthorizationException; + public enum AnnotationSetParams implements QueryParam { INTERNAL_ANNOTATION_SETS("_ias", TEXT_ARRAY, ""), ANNOTATION_SETS("_as", TEXT_ARRAY, ""), @@ -136,47 +142,6 @@ public static AnnotationSetParams getParam(String key) { } } - public void createAnnotationSetForMigration(Object id, VariableSet variableSet, AnnotationSet annotationSet) - throws CatalogDBException { - // Check if there already exists an annotation set with the same name - DataResult count = getCollection().count( - new Document() - .append(AnnotationSetParams.ANNOTATION_SET_NAME.key(), annotationSet.getId()) - .append("_id", id)); - if (count.getNumMatches() > 0) { - throw CatalogDBException.alreadyExists("AnnotationSet", "name", annotationSet.getId()); - } - - if (variableSet.isUnique()) { - // Check if the variableset has been already annotated with a different annotation set - count = getCollection().count( - new Document() - .append(AnnotationSetParams.ANNOTATION_SETS_VARIABLE_SET_ID.key(), annotationSet.getVariableSetId()) - .append("_id", id)); - if (count.getNumMatches() > 0) { - throw new CatalogDBException("Repeated annotation for a unique VariableSet"); - } - } - - List documentList = annotationConverter.annotationToDB(variableSet, annotationSet.getId(), - annotationSet.getAnnotations()); - - // Insert the annotation set in the database - Bson query = Filters.and( - Filters.eq("_id", id), - Filters.eq(AnnotationSetParams.ANNOTATION_SET_NAME.key(), new Document("$ne", annotationSet.getId())) - ); - Bson update = new Document() - .append("$addToSet", new Document(AnnotationSetParams.ANNOTATION_SETS.key(), new Document("$each", documentList))) - .append("$set", new Document(AnnotationSetParams.PRIVATE_VARIABLE_SET_MAP.key() + "." + variableSet.getUid(), - variableSet.getId())); - DataResult result = getCollection().update(query, update, null); - - if (result.getNumUpdated() != 1) { - throw CatalogDBException.alreadyExists("AnnotationSet", "name", annotationSet.getId()); - } - } - /** * Remove all possible include/exclude annotation options from the query options to do the query properly. * @@ -262,7 +227,23 @@ public boolean containsAnnotationQuery(Query query) { return query.containsKey(Constants.ANNOTATION); } - OpenCGAResult updateAnnotationSets(ClientSession clientSession, long entryUid, ObjectMap parameters, + OpenCGAResult updateAnnotationSets(ClientSession clientSession, long studyUid, List entryList, + ObjectMap parameters, List variableSetList, QueryOptions options, + boolean isVersioned) + throws CatalogDBException, CatalogParameterException, CatalogAuthorizationException { + OpenCGAResult result = OpenCGAResult.empty(Annotable.class); + if (parameters.containsKey(ANNOTATION_SETS)) { + for (Document entry : entryList) { + long entryUid = entry.get(PRIVATE_UID, Number.class).longValue(); + OpenCGAResult tmpResult = updateAnnotationSets(clientSession, studyUid, entryUid, parameters, + variableSetList, options, isVersioned); + result.append(tmpResult); + } + } + return result; + } + + OpenCGAResult updateAnnotationSets(ClientSession clientSession, long studyUid, long entryUid, ObjectMap parameters, List variableSetList, QueryOptions options, boolean isVersioned) throws CatalogDBException, CatalogParameterException, CatalogAuthorizationException { Map actionMap = options.getMap(Constants.ACTIONS, new HashMap<>()); @@ -290,27 +271,27 @@ OpenCGAResult updateAnnotationSets(ClientSession clientSess if (action == ParamUtils.BasicUpdateAction.SET) { if (CollectionUtils.isEmpty(internalAnnotationDocumentList)) { // 2.1 Remove all user existing annotations - removeAllAnnotationSets(clientSession, entryUid, isVersioned); + removeAllAnnotationSets(clientSession, studyUid, entryUid, isVersioned); } else { // 2.1 Remove all internal existing annotations - removeAllAnnotationSets(clientSession, entryUid, isVersioned, true); + removeAllAnnotationSets(clientSession, studyUid, entryUid, isVersioned, true); } } if (CollectionUtils.isEmpty(internalAnnotationDocumentList)) { // 3. Insert the list of documents - addNewAnnotations(clientSession, entryUid, annotationDocumentList, isVersioned); + addNewAnnotations(clientSession, studyUid, entryUid, annotationDocumentList, isVersioned); // 4. Set variable set map uid - id - addPrivateVariableMap(clientSession, entryUid, getPrivateVariableMapToSet(annotationSetList, variableSetList), + addPrivateVariableMap(clientSession, studyUid, entryUid, getPrivateVariableMapToSet(annotationSetList, variableSetList), isVersioned); } else { // 3. Insert the list of documents - addNewAnnotations(clientSession, entryUid, internalAnnotationDocumentList, isVersioned, true); + addNewAnnotations(clientSession, studyUid, entryUid, internalAnnotationDocumentList, isVersioned, true); // 4. Set variable set map uid - id - addPrivateVariableMap(clientSession, entryUid, getPrivateVariableMapToSet(annotationSetList, variableSetList), - isVersioned, true); + addPrivateVariableMap(clientSession, studyUid, entryUid, + getPrivateVariableMapToSet(annotationSetList, variableSetList), isVersioned, true); } } else if (action == ParamUtils.BasicUpdateAction.REMOVE) { @@ -373,7 +354,7 @@ OpenCGAResult updateAnnotationSets(ClientSession clientSess } // 1. Remove annotationSet - removeAnnotationSetByAnnotationSetId(clientSession, entryUid, annotationSet.getId(), isVersioned); + removeAnnotationSetByAnnotationSetId(clientSession, studyUid, entryUid, annotationSet.getId(), isVersioned); String variableSetId = annotationSetIdVariableSetUidMap.get(annotationSet.getId()); // Remove the annotation set from the variableSetAnnotationsets @@ -384,7 +365,7 @@ OpenCGAResult updateAnnotationSets(ClientSession clientSess // 2. Unset variable set map uid - id Map variableSetMapToRemove = new HashMap<>(); variableSetMapToRemove.put(variableSetId, null); - removePrivateVariableMap(clientSession, entryUid, variableSetMapToRemove, isVersioned); + removePrivateVariableMap(clientSession, studyUid, entryUid, variableSetMapToRemove, isVersioned); } } else if (StringUtils.isNotEmpty(annotationSet.getVariableSetId())) { VariableSet variableSet = variableSetMap.get(annotationSet.getVariableSetId()); @@ -402,12 +383,13 @@ OpenCGAResult updateAnnotationSets(ClientSession clientSess if (!variableSet.isInternal()) { // Remove all annotationSets - removeAnnotationSetByVariableSetId(clientSession, entryUid, variableSet.getUid(), isVersioned); - removePrivateVariableMap(clientSession, entryUid, variableSetMapToRemove, isVersioned); + removeAnnotationSetByVariableSetId(clientSession, studyUid, entryUid, variableSet.getUid(), isVersioned); + removePrivateVariableMap(clientSession, studyUid, entryUid, variableSetMapToRemove, isVersioned); } else { // Remove all annotationSets - removeAnnotationSetByVariableSetId(clientSession, entryUid, variableSet.getUid(), isVersioned, true); - removePrivateVariableMap(clientSession, entryUid, variableSetMapToRemove, isVersioned, true); + removeAnnotationSetByVariableSetId(clientSession, studyUid, entryUid, variableSet.getUid(), isVersioned, + true); + removePrivateVariableMap(clientSession, studyUid, entryUid, variableSetMapToRemove, isVersioned, true); } } } else { @@ -423,22 +405,26 @@ OpenCGAResult updateAnnotationSets(ClientSession clientSess List annotationDocumentList = getNewAnnotationList(Collections.singletonList(annotationSet), variableSetList); // 2. Remove all the existing annotations of the annotation set - removeAnnotationSetByAnnotationSetId(clientSession, entryUid, annotationSet.getId(), isVersioned); + removeAnnotationSetByAnnotationSetId(clientSession, studyUid, entryUid, annotationSet.getId(), isVersioned); // 3. Add new list of annotations - addNewAnnotations(clientSession, entryUid, annotationDocumentList, isVersioned); + addNewAnnotations(clientSession, studyUid, entryUid, annotationDocumentList, isVersioned); + } else { + return endWrite(startTime, 1, 0, new ArrayList<>()); } return endWrite(startTime, 1, 1, new ArrayList<>()); } - private void removePrivateVariableMap(ClientSession clientSession, long entryId, Map privateVariableMapToSet, - boolean isVersioned) throws CatalogDBException { - removePrivateVariableMap(clientSession, entryId, privateVariableMapToSet, isVersioned, false); + private void removePrivateVariableMap(ClientSession clientSession, long studyUid, long entryId, + Map privateVariableMapToSet, boolean isVersioned) + throws CatalogDBException, CatalogParameterException, CatalogAuthorizationException { + removePrivateVariableMap(clientSession, studyUid, entryId, privateVariableMapToSet, isVersioned, false); } - private void removePrivateVariableMap(ClientSession clientSession, long entryId, Map privateVariableMapToSet, - boolean isVersioned, boolean isInternal) throws CatalogDBException { + private void removePrivateVariableMap(ClientSession clientSession, long studyUid, long entryId, + Map privateVariableMapToSet, boolean isVersioned, boolean isInternal) + throws CatalogDBException, CatalogParameterException, CatalogAuthorizationException { Document queryDocument = new Document(PRIVATE_UID, entryId); if (isVersioned) { queryDocument.append(LAST_OF_VERSION, true); @@ -448,27 +434,29 @@ private void removePrivateVariableMap(ClientSession clientSession, long entryId, // We only want to remove the private variable map if it is not currently in use by any annotation set queryDocument.append(AnnotationSetParams.VARIABLE_SET_ID.key(), new Document("$ne", Long.parseLong(entry.getKey()))); - Bson unset; + UpdateDocument updateDocument = new UpdateDocument(); if (!isInternal) { - unset = Updates.unset(AnnotationSetParams.PRIVATE_VARIABLE_SET_MAP.key() + "." + entry.getKey()); + updateDocument.getUnset().add(AnnotationSetParams.PRIVATE_VARIABLE_SET_MAP.key() + "." + entry.getKey()); } else { - unset = Updates.unset(AnnotationSetParams.PRIVATE_INTERNAL_VARIABLE_SET_MAP.key() + "." + entry.getKey()); + updateDocument.getUnset().add(AnnotationSetParams.PRIVATE_INTERNAL_VARIABLE_SET_MAP.key() + "." + entry.getKey()); } - DataResult result = getCollection().update(clientSession, queryDocument, unset, new QueryOptions()); + OpenCGAResult result = transactionalUpdate(clientSession, studyUid, queryDocument, updateDocument); if (result.getNumUpdated() < 1 && result.getNumMatches() == 1) { throw new CatalogDBException("Could not remove private map information"); } } } - private void addPrivateVariableMap(ClientSession clientSession, long entryId, Map variableMap, boolean isVersioned) - throws CatalogDBException { - addPrivateVariableMap(clientSession, entryId, variableMap, isVersioned, false); + private void addPrivateVariableMap(ClientSession clientSession, long studyUid, long entryId, Map variableMap, + boolean isVersioned) + throws CatalogDBException, CatalogParameterException, CatalogAuthorizationException { + addPrivateVariableMap(clientSession, studyUid, entryId, variableMap, isVersioned, false); } - private void addPrivateVariableMap(ClientSession clientSession, long entryId, Map variableMap, boolean isVersioned, - boolean isInternal) throws CatalogDBException { + private void addPrivateVariableMap(ClientSession clientSession, long studyUid, long entryId, Map variableMap, + boolean isVersioned, boolean isInternal) + throws CatalogDBException, CatalogParameterException, CatalogAuthorizationException { Document queryDocument = new Document(PRIVATE_UID, entryId); if (isVersioned) { queryDocument.append(LAST_OF_VERSION, true); @@ -476,12 +464,12 @@ private void addPrivateVariableMap(ClientSession clientSession, long entryId, Ma String key = isInternal ? AnnotationSetParams.PRIVATE_INTERNAL_VARIABLE_SET_MAP.key() : AnnotationSetParams.PRIVATE_VARIABLE_SET_MAP.key(); - List setMap = new ArrayList<>(variableMap.size()); + UpdateDocument updateDocument = new UpdateDocument(); for (Map.Entry entry : variableMap.entrySet()) { - setMap.add(Updates.set(key + "." + entry.getKey(), entry.getValue())); + updateDocument.getSet().put(key + "." + entry.getKey(), entry.getValue()); } - DataResult result = getCollection().update(clientSession, queryDocument, Updates.combine(setMap), new QueryOptions("multi", true)); + OpenCGAResult result = transactionalUpdate(clientSession, studyUid, queryDocument, updateDocument); if (result.getNumUpdated() < 1 && result.getNumMatches() == 0) { throw new CatalogDBException("Could not add new private map information"); } @@ -502,103 +490,108 @@ private Map getPrivateVariableMapToSet(List annot return privateVariableMap; } - private void removeAllAnnotationSets(ClientSession clientSession, long entryId, boolean isVersioned) throws CatalogDBException { - removeAllAnnotationSets(clientSession, entryId, isVersioned, false); + private void removeAllAnnotationSets(ClientSession clientSession, long studyUid, long entryId, boolean isVersioned) + throws CatalogDBException, CatalogParameterException, CatalogAuthorizationException { + removeAllAnnotationSets(clientSession, studyUid, entryId, isVersioned, false); } - private void removeAllAnnotationSets(ClientSession clientSession, long entryId, boolean isVersioned, boolean internal) - throws CatalogDBException { + private void removeAllAnnotationSets(ClientSession clientSession, long studyUid, long entryId, boolean isVersioned, boolean internal) + throws CatalogDBException, CatalogParameterException, CatalogAuthorizationException { Document queryDocument = new Document(PRIVATE_UID, entryId); if (isVersioned) { queryDocument.append(LAST_OF_VERSION, true); } // We empty the annotation sets list and the private map - Bson bsonUpdate; + UpdateDocument updateDocument = new UpdateDocument(); if (!internal) { - bsonUpdate = Updates.combine( - Updates.set(AnnotationSetParams.ANNOTATION_SETS.key(), Collections.emptyList()), - Updates.set(AnnotationSetParams.PRIVATE_VARIABLE_SET_MAP.key(), Collections.emptyMap()) - ); + updateDocument.getSet().put(AnnotationSetParams.ANNOTATION_SETS.key(), Collections.emptyList()); + updateDocument.getSet().put(AnnotationSetParams.PRIVATE_VARIABLE_SET_MAP.key(), Collections.emptyMap()); } else { - bsonUpdate = Updates.combine( - Updates.set(AnnotationSetParams.INTERNAL_ANNOTATION_SETS.key(), Collections.emptyList()), - Updates.set(AnnotationSetParams.PRIVATE_INTERNAL_VARIABLE_SET_MAP.key(), Collections.emptyMap()) - ); + updateDocument.getSet().put(AnnotationSetParams.INTERNAL_ANNOTATION_SETS.key(), Collections.emptyList()); + updateDocument.getSet().put(AnnotationSetParams.PRIVATE_INTERNAL_VARIABLE_SET_MAP.key(), Collections.emptyMap()); } - DataResult result = getCollection().update(clientSession, queryDocument, bsonUpdate, new QueryOptions()); + OpenCGAResult result = transactionalUpdate(clientSession, studyUid, queryDocument, updateDocument); if (result.getNumUpdated() < 1 && result.getNumMatches() == 0) { throw new CatalogDBException("Could not remove all annotationSets"); } } - private void addNewAnnotations(ClientSession clientSession, long entryId, List annotationDocumentList, boolean isVersioned) - throws CatalogDBException { - addNewAnnotations(clientSession, entryId, annotationDocumentList, isVersioned, false); + private void addNewAnnotations(ClientSession clientSession, long studyUid, long entryId, List annotationDocumentList, + boolean isVersioned) + throws CatalogDBException, CatalogParameterException, CatalogAuthorizationException { + addNewAnnotations(clientSession, studyUid, entryId, annotationDocumentList, isVersioned, false); } - private void addNewAnnotations(ClientSession clientSession, long entryId, List annotationDocumentList, boolean isVersioned, - boolean isInternal) throws CatalogDBException { + private void addNewAnnotations(ClientSession clientSession, long studyUid, long entryId, List annotationDocumentList, + boolean isVersioned, boolean isInternal) + throws CatalogDBException, CatalogParameterException, CatalogAuthorizationException { Document queryDocument = new Document(PRIVATE_UID, entryId); if (isVersioned) { queryDocument.append(LAST_OF_VERSION, true); } String key = isInternal ? AnnotationSetParams.INTERNAL_ANNOTATION_SETS.key() : AnnotationSetParams.ANNOTATION_SETS.key(); - Bson push = Updates.addEachToSet(key, annotationDocumentList); + UpdateDocument updateDocument = new UpdateDocument(); + updateDocument.getAddToSet().put(key, annotationDocumentList); - DataResult result = getCollection().update(clientSession, queryDocument, push, new QueryOptions("multi", true)); + OpenCGAResult result = transactionalUpdate(clientSession, studyUid, queryDocument, updateDocument); if (result.getNumUpdated() < 1) { throw new CatalogDBException("Could not add new annotations"); } } - private void removeAnnotationSetByAnnotationSetId(ClientSession clientSession, long entryId, String annotationSetId, - boolean isVersioned) throws CatalogDBException { + private void removeAnnotationSetByAnnotationSetId(ClientSession clientSession, long studyUid, long entryId, String annotationSetId, + boolean isVersioned) + throws CatalogDBException, CatalogParameterException, CatalogAuthorizationException { Document queryDocument = new Document(PRIVATE_UID, entryId); if (isVersioned) { queryDocument.append(LAST_OF_VERSION, true); } - Bson pull = Updates.pull(AnnotationSetParams.ANNOTATION_SETS.key(), + UpdateDocument updateDocument = new UpdateDocument(); + updateDocument.getPull().put(AnnotationSetParams.ANNOTATION_SETS.key(), new Document(AnnotationSetParams.ANNOTATION_SET_NAME.key(), annotationSetId)); - DataResult result = getCollection().update(clientSession, queryDocument, pull, new QueryOptions("multi", true)); + OpenCGAResult result = transactionalUpdate(clientSession, studyUid, queryDocument, updateDocument); if (result.getNumUpdated() < 1) { throw new CatalogDBException("Could not delete the annotation set"); } } - private void removeAnnotationSetByVariableSetId(ClientSession clientSession, long entryId, long variableSetUid, boolean isVersioned) - throws CatalogDBException { - removeAnnotationSetByVariableSetId(clientSession, entryId, variableSetUid, isVersioned, false); + private void removeAnnotationSetByVariableSetId(ClientSession clientSession, long studyUid, long entryId, long variableSetUid, + boolean isVersioned) + throws CatalogDBException, CatalogParameterException, CatalogAuthorizationException { + removeAnnotationSetByVariableSetId(clientSession, studyUid, entryId, variableSetUid, isVersioned, false); } - private void removeAnnotationSetByVariableSetId(ClientSession clientSession, long entryUid, long variableSetUid, boolean isVersioned, - boolean isInternal) throws CatalogDBException { + private void removeAnnotationSetByVariableSetId(ClientSession clientSession, long studyUid, long entryUid, long variableSetUid, + boolean isVersioned, boolean isInternal) + throws CatalogDBException, CatalogParameterException, CatalogAuthorizationException { Document queryDocument = new Document(PRIVATE_UID, entryUid); if (isVersioned) { queryDocument.append(LAST_OF_VERSION, true); } - Bson pull; + UpdateDocument updateDocument = new UpdateDocument(); if (!isInternal) { - pull = Updates.pull(AnnotationSetParams.ANNOTATION_SETS.key(), + updateDocument.getPull().put(AnnotationSetParams.ANNOTATION_SETS.key(), new Document(AnnotationSetParams.VARIABLE_SET_ID.key(), variableSetUid)); } else { - pull = Updates.pull(AnnotationSetParams.INTERNAL_ANNOTATION_SETS.key(), + updateDocument.getPull().put(AnnotationSetParams.INTERNAL_ANNOTATION_SETS.key(), new Document(AnnotationSetParams.VARIABLE_SET_ID.key(), variableSetUid)); } - DataResult result = getCollection().update(clientSession, queryDocument, pull, new QueryOptions("multi", true)); + OpenCGAResult result = transactionalUpdate(clientSession, studyUid, queryDocument, updateDocument); if (result.getNumMatches() > 0 && result.getNumUpdated() < 1) { throw new CatalogDBException("Could not delete the annotation set"); } } protected void removeAllAnnotationSetsByVariableSetId(ClientSession clientSession, long studyUid, VariableSet variableSet, - boolean isVersioned) throws CatalogDBException { + boolean isVersioned) + throws CatalogDBException, CatalogParameterException, CatalogAuthorizationException { String annotationSetKey = variableSet.isInternal() ? AnnotationSetParams.INTERNAL_ANNOTATION_SETS.key() : AnnotationSetParams.ANNOTATION_SETS.key(); @@ -610,12 +603,12 @@ protected void removeAllAnnotationSetsByVariableSetId(ClientSession clientSessio queryDocument.append(LAST_OF_VERSION, true); } - Bson pull = new Document() - .append("$pull", new Document(annotationSetKey, - new Document(AnnotationSetParams.VARIABLE_SET_ID.key(), variableSet.getUid()))) - .append("$unset", new Document(AnnotationSetParams.PRIVATE_VARIABLE_SET_MAP.key() + "." + variableSet.getUid(), "")); + UpdateDocument updateDocument = new UpdateDocument(); + updateDocument.getPull().put(annotationSetKey, + new Document(AnnotationSetParams.VARIABLE_SET_ID.key(), variableSet.getUid())); + updateDocument.getUnset().add(AnnotationSetParams.PRIVATE_VARIABLE_SET_MAP.key() + "." + variableSet.getUid()); - DataResult result = getCollection().update(clientSession, queryDocument, pull, new QueryOptions("multi", true)); + OpenCGAResult result = transactionalUpdate(clientSession, studyUid, queryDocument, updateDocument); if (result.getNumMatches() > 0 && result.getNumUpdated() < 1) { throw new CatalogDBException("Could not delete the annotation set"); } @@ -694,7 +687,8 @@ private List getNewAnnotationList(List annotationSetLis return annotationList; } - public OpenCGAResult addVariableToAnnotations(long variableSetId, Variable variable) throws CatalogDBException { + public OpenCGAResult addVariableToAnnotations(long studyUid, long variableSetId, Variable variable) + throws CatalogDBException, CatalogParameterException, CatalogAuthorizationException { long startTime = startQuery(); // We generate the generic document that should be inserted @@ -731,30 +725,32 @@ public OpenCGAResult addVariableToAnnotations(long variableSetId, Variable varia } // Construct the query dynamically for each different annotation set and make the update - long matchCount = 0; - long modifiedCount = 0; - Bson bsonQuery; - for (String annotationId : annotationNames) { - bsonQuery = Filters.elemMatch(AnnotationSetParams.ANNOTATION_SETS.key(), Filters.and( - Filters.eq(AnnotationSetParams.VARIABLE_SET_ID.key(), variableSetId), - Filters.eq(AnnotationSetParams.ANNOTATION_SET_NAME.key(), annotationId) - )); - - // Add the annotation set key-value to the documents that will be pushed - for (Document document : documentList) { - document.put(AnnotationSetParams.ANNOTATION_SET_NAME.key(), annotationId); - } + return runTransaction(session -> { + long matchCount = 0; + long modifiedCount = 0; + Bson bsonQuery; + for (String annotationId : annotationNames) { + bsonQuery = Filters.elemMatch(AnnotationSetParams.ANNOTATION_SETS.key(), Filters.and( + Filters.eq(AnnotationSetParams.VARIABLE_SET_ID.key(), variableSetId), + Filters.eq(AnnotationSetParams.ANNOTATION_SET_NAME.key(), annotationId) + )); - // Prepare the update event - Bson update = new Document("$addToSet", new Document(AnnotationSetParams.ANNOTATION_SETS.key(), - new Document("$each", documentList))); + // Add the annotation set key-value to the documents that will be pushed + for (Document document : documentList) { + document.put(AnnotationSetParams.ANNOTATION_SET_NAME.key(), annotationId); + } - DataResult result = getCollection().update(bsonQuery, update, new QueryOptions(MongoDBCollection.MULTI, true)); - modifiedCount += result.getNumUpdated(); - matchCount += result.getNumMatches(); - } + // Prepare the update event + UpdateDocument updateDocument = new UpdateDocument(); + updateDocument.getAddToSet().put(AnnotationSetParams.ANNOTATION_SETS.key(), documentList); + + OpenCGAResult result = transactionalUpdate(session, studyUid, bsonQuery, updateDocument); + modifiedCount += result.getNumUpdated(); + matchCount += result.getNumMatches(); + } - return endWrite(startTime, matchCount, modifiedCount, new ArrayList<>()); + return endWrite(startTime, matchCount, modifiedCount, new ArrayList<>()); + }); } /** @@ -764,41 +760,45 @@ public OpenCGAResult addVariableToAnnotations(long variableSetId, Variable varia * - If fieldId is personal, it will remove all the existing entries for personal.name, personal.telephone, personal.address, etc. * - If fieldId is personal.name, it will only remove the existing entries for personal.name * + * @param studyUid Study uid. * @param variableSetId Variable set id. * @param fieldId Field id corresponds with the variable name whose annotations have to be removed. * @return A OpenCGAResult object. * @throws CatalogDBException if there is any unexpected error. + * @throws CatalogParameterException if there is any unexpected parameter. + * @throws CatalogAuthorizationException if the operation is not authorized. */ - public OpenCGAResult removeAnnotationField(long variableSetId, String fieldId) throws CatalogDBException { + public OpenCGAResult removeAnnotationField(long studyUid, long variableSetId, String fieldId) + throws CatalogDBException, CatalogParameterException, CatalogAuthorizationException { long startTime = startQuery(); -// List aggregateResult = getAnnotationDocuments(variableSetId, fieldId); - Document pull = new Document("$pull", - new Document(AnnotationSetParams.ANNOTATION_SETS.key(), - new Document() - .append(AnnotationSetParams.VARIABLE_SET_ID.key(), variableSetId) - .append(AnnotationSetParams.ID.key(), Pattern.compile("^" + fieldId)) - )); + UpdateDocument updateDocument = new UpdateDocument(); + updateDocument.getPull().put(AnnotationSetParams.ANNOTATION_SETS.key(), + new Document() + .append(AnnotationSetParams.VARIABLE_SET_ID.key(), variableSetId) + .append(AnnotationSetParams.ID.key(), Pattern.compile("^" + fieldId)) + ); Document query = new Document(AnnotationSetParams.ANNOTATION_SETS.key(), new Document("$elemMatch", new Document() .append(AnnotationSetParams.VARIABLE_SET_ID.key(), variableSetId) .append(AnnotationSetParams.ID.key(), Pattern.compile("^" + fieldId)))); - DataResult result = getCollection().update(query, pull, new QueryOptions("multi", true)); - if (result.getNumUpdated() == 0 && result.getNumMatches() > 0) { - throw new CatalogDBException("VariableSet {id: " + variableSetId + "}: An unexpected error happened when extracting the " - + "annotations for the variable " + fieldId + ". Please, report this error to the OpenCGA developers."); - } - - return new OpenCGAResult(result); + return runTransaction(clientSession -> { + OpenCGAResult result = transactionalUpdate(clientSession, studyUid, query, updateDocument); + if (result.getNumUpdated() == 0 && result.getNumMatches() > 0) { + throw new CatalogDBException("VariableSet {id: " + variableSetId + "}: An unexpected error happened when extracting the " + + "annotations for the variable " + fieldId + ". Please, report this error to the OpenCGA developers."); + } + return endWrite(startTime, result); + }); } - public OpenCGAResult getAnnotationSummary(long studyId, long variableSetId) throws CatalogDBException { + public OpenCGAResult getAnnotationSummary(long studyUid, long variableSetId) throws CatalogDBException { long startTime = startQuery(); List aggregation = new ArrayList<>(6); - aggregation.add(new Document("$match", new Document(PRIVATE_STUDY_UID, studyId))); + aggregation.add(new Document("$match", new Document(PRIVATE_STUDY_UID, studyUid))); aggregation.add(new Document("$project", new Document(AnnotationSetParams.ANNOTATION_SETS.key(), 1))); aggregation.add(new Document("$unwind", "$" + AnnotationSetParams.ANNOTATION_SETS.key())); // aggregation.add(new Document("$unwind", "$" + AnnotationSetParams.ANNOTATION_SETS_ANNOTATIONS.key())); diff --git a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/CatalogMongoDBAdaptor.java b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/CatalogMongoDBAdaptor.java new file mode 100644 index 00000000000..fa7e803d985 --- /dev/null +++ b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/CatalogMongoDBAdaptor.java @@ -0,0 +1,35 @@ +package org.opencb.opencga.catalog.db.mongodb; + +import org.bson.Document; +import org.opencb.commons.datastore.core.Query; +import org.opencb.commons.datastore.core.QueryOptions; +import org.opencb.opencga.catalog.exceptions.CatalogAuthorizationException; +import org.opencb.opencga.catalog.exceptions.CatalogDBException; +import org.opencb.opencga.catalog.exceptions.CatalogParameterException; +import org.opencb.opencga.core.config.Configuration; +import org.opencb.opencga.core.response.OpenCGAResult; +import org.slf4j.Logger; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +public abstract class CatalogMongoDBAdaptor extends MongoDBAdaptor { + + public CatalogMongoDBAdaptor(Configuration configuration, Logger logger) { + super(configuration, logger); + } + + abstract OpenCGAResult nativeGet(Query query, QueryOptions options) + throws CatalogDBException, CatalogParameterException, CatalogAuthorizationException; + + List> nativeGet(List queries, QueryOptions options) + throws CatalogDBException, CatalogParameterException, CatalogAuthorizationException { + Objects.requireNonNull(queries); + List> queryResults = new ArrayList<>(queries.size()); + for (Query query : queries) { + queryResults.add(nativeGet(query, options)); + } + return queryResults; + } +} diff --git a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/ClinicalAnalysisMongoDBAdaptor.java b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/ClinicalAnalysisMongoDBAdaptor.java index c0ea18866a4..dd5b90a22d8 100644 --- a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/ClinicalAnalysisMongoDBAdaptor.java +++ b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/ClinicalAnalysisMongoDBAdaptor.java @@ -249,7 +249,7 @@ public OpenCGAResult update(long uid, ObjectMap parameters, List va String clinicalAnalysisId = result.first().getId(); try { - return runTransaction(clientSession -> privateUpdate(clientSession, result.first(), parameters, variableSetList, + return runTransaction(clientSession -> transactionalUpdate(clientSession, result.first(), parameters, variableSetList, clinicalAuditList, queryOptions)); } catch (CatalogDBException e) { logger.error("Could not update clinical analysis {}: {}", clinicalAnalysisId, e.getMessage(), e); @@ -275,14 +275,15 @@ public OpenCGAResult update(Query query, ObjectMap parameters, List throw new NotImplementedException("Use other update method passing the ClinicalAuditList"); } - OpenCGAResult privateUpdate(ClientSession clientSession, ClinicalAnalysis clinical, ObjectMap parameters, - List variableSetList, List clinicalAuditList, QueryOptions queryOptions) + OpenCGAResult transactionalUpdate(ClientSession clientSession, ClinicalAnalysis clinical, ObjectMap parameters, + List variableSetList, List clinicalAuditList, QueryOptions queryOptions) throws CatalogDBException, CatalogParameterException, CatalogAuthorizationException { long tmpStartTime = startQuery(); String clinicalAnalysisId = clinical.getId(); long clinicalAnalysisUid = clinical.getUid(); - DataResult result = updateAnnotationSets(clientSession, clinicalAnalysisUid, parameters, variableSetList, queryOptions, false); + DataResult result = updateAnnotationSets(clientSession, clinical.getStudyUid(), clinicalAnalysisUid, parameters, variableSetList, + queryOptions, false); // Perform the update Query query = new Query(QueryParams.UID.key(), clinicalAnalysisUid); @@ -338,6 +339,42 @@ OpenCGAResult privateUpdate(ClientSession clientSession, ClinicalAnalysis clinic return endWrite(tmpStartTime, 1, 1, events); } + @Override + OpenCGAResult transactionalUpdate(ClientSession clientSession, ClinicalAnalysis entry, ObjectMap parameters, + List variableSetList, QueryOptions queryOptions) + throws CatalogParameterException, CatalogDBException, CatalogAuthorizationException { + throw new NotImplementedException("Please call to the other transactionalUpdate method passing the ClinicalAudit list"); + } + + @Override + OpenCGAResult transactionalUpdate(ClientSession clientSession, long studyUid, Bson query, + UpdateDocument updateDocument) + throws CatalogParameterException, CatalogDBException, CatalogAuthorizationException { + long tmpStartTime = startQuery(); + + Document updateOperation = updateDocument.toFinalUpdateDocument(); + if (!updateOperation.isEmpty()) { + logger.debug("Update clinical analysis. Query: {}, Update: {}", query.toBsonDocument(), updateDocument); + DataResult update = clinicalCollection.update(clientSession, query, updateOperation, null); + + if (updateDocument.getSet().getBoolean(LOCKED.key(), false)) { + // Propagate locked value to Interpretations + logger.debug("Propagating case lock to all the Interpretations"); + MongoDBIterator iterator = clinicalCollection.iterator(clientSession, query, null, clinicalConverter, + ClinicalAnalysisManager.INCLUDE_CLINICAL_IDS); + while (iterator.hasNext()) { + ClinicalAnalysis clinical = iterator.next(); + dbAdaptorFactory.getInterpretationDBAdaptor().propagateLockedFromClinicalAnalysis(clientSession, clinical, true); + } + } + + logger.debug("{} clinical analyses successfully updated", update.getNumUpdated()); + return endWrite(tmpStartTime, update.getNumMatches(), update.getNumUpdated(), Collections.emptyList()); + } else { + throw new CatalogDBException("Nothing to update"); + } + } + UpdateDocument parseAndValidateUpdateParams(ObjectMap parameters, List clinicalAuditList, Query query, QueryOptions queryOptions) throws CatalogDBException, CatalogParameterException, CatalogAuthorizationException { @@ -1166,8 +1203,8 @@ void updateClinicalAnalysisFamilyReferences(ClientSession clientSession, Family } ObjectMap params = new ObjectMap(QueryParams.FAMILY.key(), familyCopy); - OpenCGAResult result = dbAdaptorFactory.getClinicalAnalysisDBAdaptor().privateUpdate(clientSession, clinicalAnalysis, - params, Collections.emptyList(), null, QueryOptions.empty()); + OpenCGAResult result = dbAdaptorFactory.getClinicalAnalysisDBAdaptor().transactionalUpdate(clientSession, + clinicalAnalysis, params, Collections.emptyList(), null, QueryOptions.empty()); if (result.getNumUpdated() != 1) { throw new CatalogDBException("ClinicalAnalysis '" + clinicalAnalysis.getId() + "' could not be updated to the latest " + "family version of '" + family.getId() + "'"); @@ -1224,7 +1261,7 @@ void updateClinicalAnalysisPanelReferences(ClientSession clientSession, Panel pa actionMap.put(PANELS.key(), ParamUtils.BasicUpdateAction.SET); QueryOptions updateOptions = new QueryOptions(Constants.ACTIONS, actionMap); ObjectMap params = new ObjectMap(PANELS.key(), panelList); - privateUpdate(clientSession, clinicalAnalysis, params, Collections.emptyList(), null, updateOptions); + transactionalUpdate(clientSession, clinicalAnalysis, params, Collections.emptyList(), null, updateOptions); // Update references from Interpretations dbAdaptorFactory.getInterpretationDBAdaptor().updateInterpretationPanelReferences(clientSession, clinicalAnalysis, panel); diff --git a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/CohortMongoDBAdaptor.java b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/CohortMongoDBAdaptor.java index 63ff15c96fb..4a1977e1433 100644 --- a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/CohortMongoDBAdaptor.java +++ b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/CohortMongoDBAdaptor.java @@ -246,7 +246,7 @@ public OpenCGAResult update(long cohortUid, ObjectMap parameters, List privateUpdate(clientSession, documentResult.first(), parameters, variableSetList, + return runTransaction(clientSession -> transactionalUpdate(clientSession, documentResult.first(), parameters, variableSetList, queryOptions)); } catch (CatalogDBException e) { logger.error("Could not update cohort {}: {}", cohortId, e.getMessage(), e); @@ -274,7 +274,7 @@ public OpenCGAResult update(Query query, ObjectMap parameters, List while (iterator.hasNext()) { Cohort cohort = iterator.next(); try { - result.append(runTransaction(clientSession -> privateUpdate(clientSession, cohort, parameters, variableSetList, + result.append(runTransaction(clientSession -> transactionalUpdate(clientSession, cohort, parameters, variableSetList, queryOptions))); } catch (CatalogDBException | CatalogParameterException | CatalogAuthorizationException e) { logger.error("Could not update cohort {}: {}", cohort.getId(), e.getMessage(), e); @@ -285,15 +285,17 @@ public OpenCGAResult update(Query query, ObjectMap parameters, List return result; } - private OpenCGAResult privateUpdate(ClientSession clientSession, Cohort cohort, ObjectMap parameters, - List variableSetList, QueryOptions queryOptions) + @Override + OpenCGAResult transactionalUpdate(ClientSession clientSession, Cohort cohort, ObjectMap parameters, + List variableSetList, QueryOptions queryOptions) throws CatalogDBException, CatalogParameterException, CatalogAuthorizationException { long tmpStartTime = startQuery(); Query tmpQuery = new Query() .append(QueryParams.STUDY_UID.key(), cohort.getStudyUid()) .append(QueryParams.UID.key(), cohort.getUid()); - DataResult result = updateAnnotationSets(clientSession, cohort.getUid(), parameters, variableSetList, queryOptions, false); + DataResult result = updateAnnotationSets(clientSession, cohort.getStudyUid(), cohort.getUid(), parameters, variableSetList, + queryOptions, false); UpdateDocument parseUpdateDocument = parseAndValidateUpdateParams(clientSession, parameters, tmpQuery, queryOptions); Document cohortUpdate = parseUpdateDocument.toFinalUpdateDocument(); @@ -339,6 +341,22 @@ private OpenCGAResult privateUpdate(ClientSession clientSession, Cohort return endWrite(tmpStartTime, 1, 1, events); } + @Override + OpenCGAResult transactionalUpdate(ClientSession clientSession, long studyUid, Bson query, UpdateDocument updateDocument) + throws CatalogParameterException, CatalogDBException, CatalogAuthorizationException { + long tmpStartTime = startQuery(); + + Document cohortUpdate = updateDocument.toFinalUpdateDocument(); + if (cohortUpdate.isEmpty()) { + throw new CatalogDBException("Nothing to be updated"); + } + + logger.debug("Cohort update: query : {}, update: {}", query.toBsonDocument(), cohortUpdate.toBsonDocument()); + DataResult result = cohortCollection.update(clientSession, query, cohortUpdate, null); + logger.debug("{} cohorts successfully updated", result.getNumUpdated()); + return endWrite(tmpStartTime, result.getNumMatches(), result.getNumUpdated(), Collections.emptyList()); + } + private void updateCohortReferenceInSamples(ClientSession clientSession, Cohort cohort, List samples, ParamUtils.BasicUpdateAction updateAction) throws CatalogParameterException, CatalogDBException, CatalogAuthorizationException { diff --git a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/FamilyMongoDBAdaptor.java b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/FamilyMongoDBAdaptor.java index 3bb88c7042b..e2717dbddb9 100644 --- a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/FamilyMongoDBAdaptor.java +++ b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/FamilyMongoDBAdaptor.java @@ -19,7 +19,6 @@ import com.mongodb.client.ClientSession; import com.mongodb.client.model.Filters; import com.mongodb.client.model.Projections; -import com.mongodb.client.model.Updates; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.NotImplementedException; import org.apache.commons.lang3.StringUtils; @@ -332,7 +331,7 @@ public OpenCGAResult update(long familyUid, ObjectMap parameters, List privateUpdate(clientSession, familyDataResult.first(), parameters, variableSetList, queryOptions)); + -> transactionalUpdate(clientSession, familyDataResult.first(), parameters, variableSetList, queryOptions)); } catch (CatalogDBException e) { logger.error("Could not update family {}: {}", familyDataResult.first().getId(), e.getMessage(), e); throw new CatalogDBException("Could not update family " + familyDataResult.first().getId() + ": " + e.getMessage(), @@ -367,7 +366,7 @@ public OpenCGAResult update(Query query, ObjectMap parameters, List Family family = iterator.next(); try { result.append(runTransaction(clientSession -> - privateUpdate(clientSession, family, parameters, variableSetList, queryOptions))); + transactionalUpdate(clientSession, family, parameters, variableSetList, queryOptions))); } catch (CatalogDBException | CatalogParameterException | CatalogAuthorizationException e) { logger.error("Could not update family {}: {}", family.getId(), e.getMessage(), e); result.getEvents().add(new Event(Event.Type.ERROR, family.getId(), e.getMessage())); @@ -377,18 +376,31 @@ public OpenCGAResult update(Query query, ObjectMap parameters, List return result; } - OpenCGAResult privateUpdate(ClientSession clientSession, Family family, ObjectMap parameters, List variableSetList, - QueryOptions queryOptions) + @Override + OpenCGAResult transactionalUpdate(ClientSession clientSession, Family family, ObjectMap parameters, + List variableSetList, QueryOptions queryOptions) throws CatalogDBException, CatalogParameterException, CatalogAuthorizationException { long tmpStartTime = startQuery(); + long studyUid = family.getStudyUid(); + long familyUid = family.getUid(); + if (studyUid <= 0) { + throw new CatalogDBException("Unexpected studyUid value received"); + } + if (familyUid <= 0) { + throw new CatalogDBException("Unexpected familyUid value received"); + } + Query tmpQuery = new Query() - .append(QueryParams.STUDY_UID.key(), family.getStudyUid()) - .append(QueryParams.UID.key(), family.getUid()); + .append(QueryParams.STUDY_UID.key(), studyUid) + .append(QueryParams.UID.key(), familyUid); + List fieldsToInclude = Arrays.asList(QueryParams.ID.key(), QueryParams.UID.key(), QueryParams.VERSION.key(), + QueryParams.STUDY_UID.key(), QueryParams.MEMBERS.key() + "." + IndividualDBAdaptor.QueryParams.ID.key()); Bson bsonQuery = parseQuery(tmpQuery); - return versionedMongoDBAdaptor.update(clientSession, bsonQuery, () -> { - DataResult result = updateAnnotationSets(clientSession, family.getUid(), parameters, variableSetList, queryOptions, - true); + return versionedMongoDBAdaptor.update(clientSession, bsonQuery, fieldsToInclude, (entrylist) -> { + String familyId = entrylist.get(0).getString(QueryParams.ID.key()); + DataResult result = updateAnnotationSets(clientSession, studyUid, familyUid, parameters, + variableSetList, queryOptions, true); List familyMemberIds = family.getMembers().stream().map(Individual::getId).collect(Collectors.toList()); boolean updateRoles = queryOptions.getBoolean(ParamConstants.FAMILY_UPDATE_ROLES_PARAM); boolean updatePedigree = queryOptions.getBoolean(ParamConstants.FAMILY_UPDATE_PEDIGREEE_GRAPH_PARAM); @@ -425,15 +437,14 @@ OpenCGAResult privateUpdate(ClientSession clientSession, Family family, if (!familyMemberIds.isEmpty()) { // Fetch individuals with relevant information to guess the relationship Query individualQuery = new Query() - .append(IndividualDBAdaptor.QueryParams.STUDY_UID.key(), family.getStudyUid()) + .append(IndividualDBAdaptor.QueryParams.STUDY_UID.key(), studyUid) .append(IndividualDBAdaptor.QueryParams.ID.key(), familyMemberIds); QueryOptions relationshipOptions = dbAdaptorFactory.getCatalogIndividualDBAdaptor().fixOptionsForRelatives( null); OpenCGAResult memberResult = dbAdaptorFactory.getCatalogIndividualDBAdaptor().get(clientSession, individualQuery, relationshipOptions); family.setMembers(memberResult.getResults()); - Map> roles = calculateRoles(clientSession, family - .getStudyUid(), family); + Map> roles = calculateRoles(clientSession, studyUid, family); parameters.put(QueryParams.ROLES.key(), roles); } else { parameters.put(QueryParams.ROLES.key(), Collections.emptyMap()); @@ -477,8 +488,8 @@ OpenCGAResult privateUpdate(ClientSession clientSession, Family family, // Fetch members (we don't trust those from the Family object because they could have been updated previously) Query query = new Query() - .append(IndividualDBAdaptor.QueryParams.FAMILY_IDS.key(), family.getId()) - .append(IndividualDBAdaptor.QueryParams.STUDY_UID.key(), family.getStudyUid()); + .append(IndividualDBAdaptor.QueryParams.FAMILY_IDS.key(), familyId) + .append(IndividualDBAdaptor.QueryParams.STUDY_UID.key(), studyUid); OpenCGAResult individualResult = dbAdaptorFactory.getCatalogIndividualDBAdaptor().get(clientSession, query, IndividualManager.INCLUDE_INDIVIDUAL_IDS); List memberIds = individualResult.getResults().stream().map(Individual::getId) @@ -491,12 +502,12 @@ OpenCGAResult privateUpdate(ClientSession clientSession, Family family, } if (result.getNumMatches() == 0) { - throw new CatalogDBException("Family " + family.getId() + " not found"); + throw new CatalogDBException("Family " + familyId + " not found"); } if (result.getNumUpdated() == 0) { - events.add(new Event(Event.Type.WARNING, family.getId(), "Family was already updated")); + events.add(new Event(Event.Type.WARNING, familyId, "Family was already updated")); } - logger.debug("Family {} successfully updated", family.getId()); + logger.debug("Family {} successfully updated", familyId); } return endWrite(tmpStartTime, 1, 1, events); @@ -504,6 +515,29 @@ OpenCGAResult privateUpdate(ClientSession clientSession, Family family, this::iterator, (DBIterator iterator) -> updateReferencesAfterFamilyVersionIncrement(clientSession, iterator)); } + @Override + OpenCGAResult transactionalUpdate(ClientSession clientSession, long studyUid, Bson query, UpdateDocument updateDocument) + throws CatalogParameterException, CatalogDBException, CatalogAuthorizationException { + long tmpStartTime = startQuery(); + List fieldsToInclude = Arrays.asList(QueryParams.ID.key(), QueryParams.UID.key(), QueryParams.VERSION.key(), + QueryParams.STUDY_UID.key(), QueryParams.MEMBERS.key() + "." + IndividualDBAdaptor.QueryParams.ID.key()); + + return versionedMongoDBAdaptor.update(clientSession, query, fieldsToInclude, (entrylist) -> { + Document familyUpdate = updateDocument.toFinalUpdateDocument(); + + if (familyUpdate.isEmpty()) { + throw new CatalogDBException("Nothing to be updated"); + } + + logger.debug("Family update: query : {}, update: {}", query.toBsonDocument(), familyUpdate.toBsonDocument()); + DataResult result = familyCollection.update(clientSession, query, familyUpdate, + new QueryOptions(MongoDBCollection.MULTI, true)); + logger.debug("{} families successfully updated", result.getNumUpdated()); + return endWrite(tmpStartTime, result.getNumMatches(), result.getNumUpdated(), Collections.emptyList()); + }, Arrays.asList(QueryParams.MEMBERS_ID.key(), QueryParams.MEMBERS_SAMPLES_ID.key()), + this::iterator, (DBIterator iterator) -> updateReferencesAfterFamilyVersionIncrement(clientSession, iterator)); + } + private PedigreeGraph computePedigreeGraph(ClientSession clientSession, Family family) throws CatalogDBException, CatalogParameterException, CatalogAuthorizationException { Query query = new Query() @@ -590,18 +624,11 @@ void updateIndividualReferencesInFamily(ClientSession clientSession, long studyU ObjectMap params = new ObjectMap(FamilyDBAdaptor.QueryParams.MEMBERS.key(), members); UpdateDocument updateDocument = parseAndValidateUpdateParams(clientSession, params, tmpQuery); - Document bsonUpdate = updateDocument.toFinalUpdateDocument(); Bson bsonQuery = parseQuery(tmpQuery); - versionedMongoDBAdaptor.update(clientSession, bsonQuery, () -> { - DataResult result = familyCollection.update(clientSession, bsonQuery, bsonUpdate, QueryOptions.empty()); - if (result.getNumUpdated() != 1) { - throw new CatalogDBException("Family '" + family.getId() + "' could not be updated to the latest member" - + " versions"); - } - return result; - }, Arrays.asList(QueryParams.MEMBERS_ID.key(), QueryParams.MEMBERS_SAMPLES_ID.key()), - this::iterator, - (DBIterator fIterator) -> updateReferencesAfterFamilyVersionIncrement(clientSession, fIterator)); + OpenCGAResult result = transactionalUpdate(clientSession, studyUid, bsonQuery, updateDocument); + if (result.getNumUpdated() != 1) { + throw new CatalogDBException("Family '" + family.getId() + "' could not be updated to the latest member versions"); + } } } } @@ -657,12 +684,9 @@ void updateIndividualIdFromFamilies(ClientSession clientSession, long studyUid, .append(QueryParams.STUDY_UID.key(), studyUid) .append(QueryParams.UID.key(), family.getUid()) ); - versionedMongoDBAdaptor.update(clientSession, bsonQuery, () -> { - Bson update = Updates.set(QueryParams.ROLES.key(), getMongoDBDocument(roles, QueryParams.ROLES.key())); - return familyCollection.update(clientSession, bsonQuery, update, QueryOptions.empty()); - }, Arrays.asList(QueryParams.MEMBERS_ID.key(), QueryParams.MEMBERS_SAMPLES_ID.key()), - this::iterator, - (DBIterator fIterator) -> updateReferencesAfterFamilyVersionIncrement(clientSession, fIterator)); + UpdateDocument updateDocument = new UpdateDocument(); + updateDocument.getSet().put(QueryParams.ROLES.key(), getMongoDBDocument(roles, QueryParams.ROLES.key())); + transactionalUpdate(clientSession, studyUid, bsonQuery, updateDocument); } } } diff --git a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/FileMongoDBAdaptor.java b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/FileMongoDBAdaptor.java index 4d0e93e23c5..d283a09fd2b 100644 --- a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/FileMongoDBAdaptor.java +++ b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/FileMongoDBAdaptor.java @@ -31,7 +31,6 @@ import org.opencb.opencga.catalog.db.api.FileDBAdaptor; import org.opencb.opencga.catalog.db.api.SampleDBAdaptor; import org.opencb.opencga.catalog.db.mongodb.converters.FileConverter; -import org.opencb.opencga.catalog.db.mongodb.converters.SampleConverter; import org.opencb.opencga.catalog.db.mongodb.iterators.FileCatalogMongoDBIterator; import org.opencb.opencga.catalog.exceptions.CatalogAuthorizationException; import org.opencb.opencga.catalog.exceptions.CatalogDBException; @@ -153,14 +152,14 @@ public OpenCGAResult insertWithVirtualFile(long studyId, File file, File virtual ObjectMap params = new ObjectMap(QueryParams.RELATED_FILES.key(), Collections.singletonList( new FileRelatedFile(file, FileRelatedFile.Relation.MULTIPART) )); - privateUpdate(clientSession, virtualFile, params, null, qOptions); + transactionalUpdate(clientSession, virtualFile, params, null, qOptions); } // Add multipart file in physical file ObjectMap params = new ObjectMap(QueryParams.RELATED_FILES.key(), Collections.singletonList( new FileRelatedFile(virtualFile, FileRelatedFile.Relation.MULTIPART) )); - privateUpdate(clientSession, file, params, null, qOptions); + transactionalUpdate(clientSession, file, params, null, qOptions); return endWrite(tmpStartTime, 1, 1, 0, 0, null); }, @@ -214,9 +213,7 @@ long insert(ClientSession clientSession, long studyId, File file, List e logger.debug("Updating list of fileIds in batch of {} samples...", sampleList.size()); for (Sample sample : sampleList) { - SampleConverter sampleConverter = dbAdaptorFactory.getCatalogSampleDBAdaptor().getSampleConverter(); - Document sampleDocument = sampleConverter.convertToStorageType(sample); - dbAdaptorFactory.getCatalogSampleDBAdaptor().privateUpdate(clientSession, sampleDocument, params, null, + dbAdaptorFactory.getCatalogSampleDBAdaptor().transactionalUpdate(clientSession, sample, params, null, sampleUpdateOptions); } @@ -336,7 +333,7 @@ public OpenCGAResult update(long fileUid, ObjectMap parameters, List privateUpdate(clientSession, fileDataResult.first(), parameters, + return runTransaction(clientSession -> transactionalUpdate(clientSession, fileDataResult.first(), parameters, variableSetList, queryOptions)); } catch (CatalogDBException e) { logger.error("Could not update file {}: {}", fileDataResult.first().getPath(), e.getMessage(), e); @@ -362,7 +359,7 @@ public OpenCGAResult update(Query query, ObjectMap parameters, List while (iterator.hasNext()) { File file = iterator.next(); try { - result.append(runTransaction(clientSession -> privateUpdate(clientSession, file, parameters, variableSetList, + result.append(runTransaction(clientSession -> transactionalUpdate(clientSession, file, parameters, variableSetList, queryOptions))); } catch (CatalogDBException e) { logger.error("Could not update file {}: {}", file.getPath(), e.getMessage(), e); @@ -373,20 +370,24 @@ public OpenCGAResult update(Query query, ObjectMap parameters, List return result; } - OpenCGAResult privateUpdate(ClientSession clientSession, File file, ObjectMap parameters, List variableSetList, - QueryOptions queryOptions) - throws CatalogDBException, CatalogParameterException, CatalogAuthorizationException { + @Override + OpenCGAResult transactionalUpdate(ClientSession clientSession, File file, ObjectMap parameters, + List variableSetList, QueryOptions queryOptions) + throws CatalogParameterException, CatalogDBException, CatalogAuthorizationException { long tmpStartTime = startQuery(); + long studyUid = file.getStudyUid(); + long fileUid = file.getUid(); Query tmpQuery = new Query() - .append(QueryParams.STUDY_UID.key(), file.getStudyUid()) - .append(QueryParams.UID.key(), file.getUid()); + .append(QueryParams.STUDY_UID.key(), studyUid) + .append(QueryParams.UID.key(), fileUid); // We perform the update. Bson queryBson = parseQuery(tmpQuery); - DataResult result = updateAnnotationSets(clientSession, file.getUid(), parameters, variableSetList, queryOptions, false); + DataResult result = updateAnnotationSets(clientSession, studyUid, fileUid, parameters, variableSetList, + queryOptions, false); - UpdateDocument updateDocument = getValidatedUpdateParams(clientSession, file.getStudyUid(), parameters, tmpQuery, queryOptions); + UpdateDocument updateDocument = getValidatedUpdateParams(clientSession, studyUid, parameters, tmpQuery, queryOptions); Document fileUpdate = updateDocument.toFinalUpdateDocument(); if (fileUpdate.isEmpty() && result.getNumUpdated() == 0) { @@ -406,7 +407,7 @@ OpenCGAResult privateUpdate(ClientSession clientSession, File file, Obje if (parameters.containsKey(QueryParams.SIZE.key())) { long newDiskUsage = parameters.getLong(QueryParams.SIZE.key()); long difDiskUsage = newDiskUsage - file.getSize(); - dbAdaptorFactory.getCatalogStudyDBAdaptor().updateDiskUsage(clientSession, file.getStudyUid(), difDiskUsage); + dbAdaptorFactory.getCatalogStudyDBAdaptor().updateDiskUsage(clientSession, studyUid, difDiskUsage); } updateSampleReferences(clientSession, file, updateDocument); @@ -423,6 +424,26 @@ OpenCGAResult privateUpdate(ClientSession clientSession, File file, Obje return endWrite(tmpStartTime, 1, 1, events); } + @Override + OpenCGAResult transactionalUpdate(ClientSession clientSession, long studyUid, Bson query, UpdateDocument updateDocument) + throws CatalogDBException { + long tmpStartTime = startQuery(); + + Document fileUpdate = updateDocument.toFinalUpdateDocument(); + + if (fileUpdate.isEmpty()) { + throw new CatalogDBException("Nothing to be updated"); + } + + List events = new ArrayList<>(); + logger.debug("Update file. Query: {}, Update: {}", query.toBsonDocument(), fileUpdate.toBsonDocument()); + + DataResult result = fileCollection.update(clientSession, query, fileUpdate, null); + logger.debug("{} file(s) successfully updated", result.getNumUpdated()); + + return endWrite(tmpStartTime, result.getNumMatches(), result.getNumUpdated(), events); + } + private void updateSampleReferences(ClientSession clientSession, File file, UpdateDocument updateDocument) throws CatalogDBException, CatalogParameterException, CatalogAuthorizationException { if (!updateDocument.getAttributes().isEmpty()) { @@ -456,38 +477,36 @@ private void updateSampleReferences(ClientSession clientSession, File file, Upda sampleUpdate = new UpdateDocument(); sampleUpdate.getSet().append(SampleDBAdaptor.QueryParams.FILE_IDS.key() + ".$", newFileId); - dbAdaptorFactory.getCatalogSampleDBAdaptor().getCollection().update(clientSession, sampleBsonQuery, - sampleUpdate.toFinalUpdateDocument(), new QueryOptions(MongoDBCollection.MULTI, true)); + dbAdaptorFactory.getCatalogSampleDBAdaptor().transactionalUpdate(clientSession, file.getStudyUid(), sampleBsonQuery, + sampleUpdate); } if (addedSamples != null && !addedSamples.isEmpty()) { Query query = new Query() .append(SampleDBAdaptor.QueryParams.STUDY_UID.key(), file.getStudyUid()) .append(SampleDBAdaptor.QueryParams.UID.key(), addedSamples.getAsLongList(file.getId())); - List sampleList = dbAdaptorFactory.getCatalogSampleDBAdaptor().nativeGet(clientSession, query, - dbAdaptorFactory.getCatalogSampleDBAdaptor().SAMPLE_FETCH_FOR_UPDATE_OPTIONS).getResults(); + sampleBsonQuery = dbAdaptorFactory.getCatalogSampleDBAdaptor().parseQuery(query, null); ObjectMap actionMap = new ObjectMap(SampleDBAdaptor.QueryParams.FILE_IDS.key(), BasicUpdateAction.ADD.name()); QueryOptions sampleUpdateOptions = new QueryOptions(Constants.ACTIONS, actionMap); + updateDocument = dbAdaptorFactory.getCatalogSampleDBAdaptor().parseAndValidateUpdateParams(clientSession, + file.getStudyUid(), params, query, sampleUpdateOptions); - for (Document sampleDocument : sampleList) { - dbAdaptorFactory.getCatalogSampleDBAdaptor().privateUpdate(clientSession, sampleDocument, params, null, - sampleUpdateOptions); - } + dbAdaptorFactory.getCatalogSampleDBAdaptor().transactionalUpdate(clientSession, file.getStudyUid(), sampleBsonQuery, + updateDocument); } if (removedSamples != null && !removedSamples.isEmpty()) { Query query = new Query() .append(SampleDBAdaptor.QueryParams.STUDY_UID.key(), file.getStudyUid()) .append(SampleDBAdaptor.QueryParams.UID.key(), removedSamples.getAsLongList(file.getId())); - List sampleList = dbAdaptorFactory.getCatalogSampleDBAdaptor().nativeGet(clientSession, query, - dbAdaptorFactory.getCatalogSampleDBAdaptor().SAMPLE_FETCH_FOR_UPDATE_OPTIONS).getResults(); + sampleBsonQuery = dbAdaptorFactory.getCatalogSampleDBAdaptor().parseQuery(query, null); ObjectMap actionMap = new ObjectMap(SampleDBAdaptor.QueryParams.FILE_IDS.key(), BasicUpdateAction.REMOVE.name()); QueryOptions sampleUpdateOptions = new QueryOptions(Constants.ACTIONS, actionMap); + updateDocument = dbAdaptorFactory.getCatalogSampleDBAdaptor().parseAndValidateUpdateParams(clientSession, + file.getStudyUid(), params, query, sampleUpdateOptions); - for (Document sampleDocument : sampleList) { - dbAdaptorFactory.getCatalogSampleDBAdaptor().privateUpdate(clientSession, sampleDocument, params, null, - sampleUpdateOptions); - } + dbAdaptorFactory.getCatalogSampleDBAdaptor().transactionalUpdate(clientSession, file.getStudyUid(), sampleBsonQuery, + updateDocument); } } } @@ -719,6 +738,12 @@ private UpdateDocument getValidatedUpdateParams(ClientSession clientSession, lon nestedPut(QueryParams.STATUS_DATE.key(), TimeUtils.getTime(), document.getSet()); } + if (parameters.containsKey(QueryParams.INTERNAL_STATUS_ID.key())) { + FileStatus fileStatus = new FileStatus(parameters.getString(QueryParams.INTERNAL_STATUS_ID.key())); + Document fileStatusDoc = getMongoDBDocument(fileStatus, QueryParams.INTERNAL_STATUS.key()); + document.getSet().put(QueryParams.INTERNAL_STATUS.key(), fileStatusDoc); + } + if (!document.toFinalUpdateDocument().isEmpty()) { String time = TimeUtils.getTime(); if (StringUtils.isEmpty(parameters.getString(MODIFICATION_DATE.key()))) { diff --git a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/IndividualMongoDBAdaptor.java b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/IndividualMongoDBAdaptor.java index d9c6857200a..f325a1cf6e8 100644 --- a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/IndividualMongoDBAdaptor.java +++ b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/IndividualMongoDBAdaptor.java @@ -18,7 +18,6 @@ import com.mongodb.client.ClientSession; import com.mongodb.client.model.Filters; -import com.mongodb.client.model.Updates; import org.apache.commons.lang3.NotImplementedException; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.time.StopWatch; @@ -214,13 +213,13 @@ Individual insert(ClientSession clientSession, long studyId, Individual individu void updateFamilyReferences(ClientSession clientSession, long studyUid, List individualIds, String familyId, ParamUtils.BasicUpdateAction action) throws CatalogParameterException, CatalogDBException, CatalogAuthorizationException { - Bson bsonUpdate; + UpdateDocument updateDocument = new UpdateDocument(); switch (action) { case ADD: - bsonUpdate = Updates.addToSet(QueryParams.FAMILY_IDS.key(), familyId); + updateDocument.getAddToSet().put(QueryParams.FAMILY_IDS.key(), familyId); break; case REMOVE: - bsonUpdate = Updates.pull(QueryParams.FAMILY_IDS.key(), familyId); + updateDocument.getPull().put(QueryParams.FAMILY_IDS.key(), familyId); break; case SET: default: @@ -232,15 +231,7 @@ void updateFamilyReferences(ClientSession clientSession, long studyUid, List { - DataResult update = individualCollection.update(clientSession, bsonQuery, bsonUpdate, - new QueryOptions(MongoDBCollection.MULTI, true)); - if (update.getNumMatches() == 0) { - throw new CatalogDBException("Could not update family references in individuals"); - } - return null; - }, Collections.singletonList(QueryParams.SAMPLES_IDS.key()), this::iterator, - (DBIterator iterator) -> updateReferencesAfterIndividualVersionIncrement(clientSession, studyUid, iterator)); + transactionalUpdate(clientSession, studyUid, bsonQuery, updateDocument); } @Override @@ -335,20 +326,11 @@ public OpenCGAResult update(long id, ObjectMap parameters, QueryOptions queryOpt @Override public OpenCGAResult update(long individualUid, ObjectMap parameters, List variableSetList, QueryOptions queryOptions) throws CatalogDBException, CatalogParameterException, CatalogAuthorizationException { - QueryOptions options = new QueryOptions(QueryOptions.INCLUDE, - Arrays.asList(QueryParams.ID.key(), QueryParams.UID.key(), QueryParams.VERSION.key(), QueryParams.STUDY_UID.key())); - OpenCGAResult dataResult = get(individualUid, options); - - if (dataResult.getNumResults() == 0) { - throw new CatalogDBException("Could not update individual. Individual uid '" + individualUid + "' not found."); - } - try { - return runTransaction(clientSession -> privateUpdate(clientSession, dataResult.first(), parameters, variableSetList, + return runTransaction(clientSession -> transactionalUpdate(clientSession, individualUid, parameters, variableSetList, queryOptions)); } catch (CatalogDBException e) { - logger.error("Could not update individual {}: {}", dataResult.first().getId(), e.getMessage(), e); - throw new CatalogDBException("Could not update individual " + dataResult.first().getId() + ": " + e.getMessage(), e.getCause()); + throw new CatalogDBException("Could not update individual: " + e.getMessage(), e.getCause()); } } @@ -379,7 +361,7 @@ public OpenCGAResult update(Query query, ObjectMap parameters, List Individual individual = iterator.next(); try { - result.append(runTransaction(clientSession -> privateUpdate(clientSession, individual, parameters, variableSetList, + result.append(runTransaction(clientSession -> transactionalUpdate(clientSession, individual, parameters, variableSetList, queryOptions))); } catch (CatalogDBException | CatalogParameterException | CatalogAuthorizationException e) { logger.error("Could not update individual {}: {}", individual.getId(), e.getMessage(), e); @@ -390,82 +372,215 @@ public OpenCGAResult update(Query query, ObjectMap parameters, List return result; } - OpenCGAResult privateUpdate(ClientSession clientSession, Individual individual, ObjectMap parameters, - List variableSetList, QueryOptions queryOptions) + @Override + OpenCGAResult transactionalUpdate(ClientSession clientSession, Individual individual, ObjectMap parameters, + List variableSetList, QueryOptions queryOptions) throws CatalogDBException, CatalogParameterException, CatalogAuthorizationException { long tmpStartTime = startQuery(); + long studyUid = individual.getStudyUid(); + long individualUid = individual.getUid(); + if (studyUid <= 0) { + throw new CatalogDBException("Unexpected studyUid value received"); + } + if (individualUid <= 0) { + throw new CatalogDBException("Unexpected individualUid value received"); + } Query tmpQuery = new Query() - .append(QueryParams.STUDY_UID.key(), individual.getStudyUid()) - .append(QueryParams.UID.key(), individual.getUid()); + .append(QueryParams.STUDY_UID.key(), studyUid) + .append(QueryParams.UID.key(), individualUid); + List fieldsToInclude = Arrays.asList(QueryParams.ID.key(), QueryParams.UID.key(), QueryParams.VERSION.key(), + QueryParams.STUDY_UID.key()); + Bson bson = parseQuery(tmpQuery); - return versionedMongoDBAdaptor.update(clientSession, bson, () -> { - DataResult result = updateAnnotationSets(clientSession, individual.getUid(), parameters, variableSetList, queryOptions, true); - UpdateDocument updateDocument = parseAndValidateUpdateParams(clientSession, parameters, tmpQuery, queryOptions); - Document individualUpdate = updateDocument.toFinalUpdateDocument(); - - if (individualUpdate.isEmpty() && result.getNumUpdated() == 0) { - if (!parameters.isEmpty()) { - logger.error("Non-processed update parameters: {}", parameters.keySet()); - } - throw new CatalogDBException("Nothing to be updated"); - } + return versionedMongoDBAdaptor.update(clientSession, bson, fieldsToInclude, (entryList) -> { + String individualId = entryList.get(0).getString(QueryParams.ID.key()); + DataResult result = updateAnnotationSets(clientSession, studyUid, individualUid, parameters, + variableSetList, queryOptions, true); + UpdateDocument updateDocument = parseAndValidateUpdateParams(clientSession, parameters, tmpQuery, queryOptions); + Document individualUpdate = updateDocument.toFinalUpdateDocument(); + + if (individualUpdate.isEmpty() && result.getNumUpdated() == 0) { + if (!parameters.isEmpty()) { + logger.error("Non-processed update parameters: {}", parameters.keySet()); + } + throw new CatalogDBException("Nothing to be updated"); + } - List events = new ArrayList<>(); - if (!individualUpdate.isEmpty()) { - Bson finalQuery = parseQuery(tmpQuery); + List events = new ArrayList<>(); + if (!individualUpdate.isEmpty()) { + Bson finalQuery = parseQuery(tmpQuery); - logger.debug("Individual update: query : {}, update: {}", finalQuery.toBsonDocument(), individualUpdate.toBsonDocument()); + logger.debug("Individual update: query : {}, update: {}", finalQuery.toBsonDocument(), + individualUpdate.toBsonDocument()); - result = individualCollection.update(clientSession, finalQuery, individualUpdate, new QueryOptions("multi", true)); + result = individualCollection.update(clientSession, finalQuery, individualUpdate, new QueryOptions("multi", true)); - if (result.getNumMatches() == 0) { - throw new CatalogDBException("Individual " + individual.getId() + " not found"); - } - if (result.getNumUpdated() == 0) { - events.add(new Event(Event.Type.WARNING, individual.getId(), "Individual was already updated")); - } + if (result.getNumMatches() == 0) { + throw new CatalogDBException("Individual " + individualId + " not found"); + } + if (result.getNumUpdated() == 0) { + events.add(new Event(Event.Type.WARNING, individualId, "Individual was already updated")); + } - if (!updateDocument.getAttributes().isEmpty()) { - List addedSamples = updateDocument.getAttributes().getAsLongList("ADDED_SAMPLES"); - List removedSamples = updateDocument.getAttributes().getAsLongList("REMOVED_SAMPLES"); + if (!updateDocument.getAttributes().isEmpty()) { + List addedSamples = updateDocument.getAttributes().getAsLongList("ADDED_SAMPLES"); + List removedSamples = updateDocument.getAttributes().getAsLongList("REMOVED_SAMPLES"); - // Set new individual reference - dbAdaptorFactory.getCatalogSampleDBAdaptor().updateIndividualFromSampleCollection(clientSession, - individual.getStudyUid(), addedSamples, individual.getId()); + // Set new individual reference + dbAdaptorFactory.getCatalogSampleDBAdaptor().updateIndividualFromSampleCollection(clientSession, + studyUid, addedSamples, individualId); - // Set individual reference to "" - dbAdaptorFactory.getCatalogSampleDBAdaptor().updateIndividualFromSampleCollection(clientSession, - individual.getStudyUid(), removedSamples, ""); - } + // Set individual reference to "" + dbAdaptorFactory.getCatalogSampleDBAdaptor().updateIndividualFromSampleCollection(clientSession, + studyUid, removedSamples, ""); + } - // If the list of disorders or phenotypes is altered, we will need to update the corresponding effective lists - // of the families associated (if any) - if (parameters.containsKey(QueryParams.DISORDERS.key()) || parameters.containsKey(QueryParams.PHENOTYPES.key())) { - recalculateFamilyDisordersPhenotypes(clientSession, individual); - } + // If the list of disorders or phenotypes is altered, we will need to update the corresponding effective lists + // of the families associated (if any) + if (parameters.containsKey(QueryParams.DISORDERS.key()) || parameters.containsKey(QueryParams.PHENOTYPES.key())) { + recalculateFamilyDisordersPhenotypes(clientSession, studyUid, individualUid); + } - if (StringUtils.isNotEmpty(parameters.getString(QueryParams.ID.key()))) { - // We need to update the individual id reference in all its samples - dbAdaptorFactory.getCatalogSampleDBAdaptor().updateIndividualIdFromSamples(clientSession, individual.getStudyUid(), - individual.getId(), parameters.getString(QueryParams.ID.key())); + if (StringUtils.isNotEmpty(parameters.getString(QueryParams.ID.key()))) { + // We need to update the individual id reference in all its samples + dbAdaptorFactory.getCatalogSampleDBAdaptor().updateIndividualIdFromSamples(clientSession, studyUid, + individualId, parameters.getString(QueryParams.ID.key())); - // Update the family roles - familyDBAdaptor.updateIndividualIdFromFamilies(clientSession, individual.getStudyUid(), - individual.getUid(), individual.getId(), parameters.getString(QueryParams.ID.key())); - } + // Update the family roles + familyDBAdaptor.updateIndividualIdFromFamilies(clientSession, studyUid, individualUid, individualId, + parameters.getString(QueryParams.ID.key())); + } - if (parameters.containsKey(QueryParams.FATHER_UID.key()) || parameters.containsKey(QueryParams.MOTHER_UID.key())) { - // If the parents have changed, we need to check family roles - recalculateFamilyRolesForMember(clientSession, individual.getStudyUid(), individual.getUid()); - } + if (parameters.containsKey(QueryParams.FATHER_UID.key()) || parameters.containsKey(QueryParams.MOTHER_UID.key())) { + // If the parents have changed, we need to check family roles + recalculateFamilyRolesForMember(clientSession, studyUid, individualUid); + } - logger.debug("Individual {} successfully updated", individual.getId()); - } + logger.debug("Individual {} successfully updated", individualId); + } - return endWrite(tmpStartTime, 1, 1, events); - }, Collections.singletonList(QueryParams.SAMPLES_IDS.key()), this::iterator, - (DBIterator iterator) -> updateReferencesAfterIndividualVersionIncrement(clientSession, - individual.getStudyUid(), iterator)); + return endWrite(tmpStartTime, 1, 1, events); + }, Collections.singletonList(QueryParams.SAMPLES_IDS.key()), this::iterator, + (DBIterator iterator) -> updateReferencesAfterIndividualVersionIncrement(clientSession, studyUid, iterator)); + } + + OpenCGAResult transactionalUpdate(ClientSession clientSession, long studyUid, Bson query, UpdateDocument updateDocument) + throws CatalogParameterException, CatalogDBException, CatalogAuthorizationException { + long tmpStartTime = startQuery(); + List fieldsToInclude = Arrays.asList(QueryParams.ID.key(), QueryParams.UID.key(), QueryParams.VERSION.key(), + QueryParams.STUDY_UID.key()); + + return versionedMongoDBAdaptor.update(clientSession, query, fieldsToInclude, (entryList) -> { + List events = new ArrayList<>(); + Document update = updateDocument.toFinalUpdateDocument(); + if (!update.isEmpty()) { + logger.debug("Individual update: query : {}, update: {}", query.toBsonDocument(), update.toBsonDocument()); + DataResult result = individualCollection.update(clientSession, query, update, + new QueryOptions(MongoDBCollection.MULTI, true)); + List individualIds = entryList.stream().map(x -> x.getString(QueryParams.ID.key())) + .collect(Collectors.toList()); + if (result.getNumUpdated() == 0) { + for (String individualId : individualIds) { + events.add(new Event(Event.Type.WARNING, individualId, "Individual was already updated")); + } + } + + logger.debug("Individual(s) {} successfully updated", StringUtils.join(individualIds, ", ")); + return endWrite(tmpStartTime, result.getNumMatches(), result.getNumUpdated(), events); + } else { + return endWrite(tmpStartTime, entryList.size(), 0, events); + } + }, Collections.singletonList(QueryParams.SAMPLES_IDS.key()), this::iterator, + (DBIterator iterator) -> updateReferencesAfterIndividualVersionIncrement(clientSession, studyUid, iterator)); + } + + // If we know the study uid, we should be calling to the other transactionalUpdate method that receives the entire object instead of + // the uid + @Deprecated + OpenCGAResult transactionalUpdate(ClientSession clientSession, long individualUid, ObjectMap parameters, + List variableSetList, QueryOptions queryOptions) + throws CatalogDBException, CatalogParameterException, CatalogAuthorizationException { + long tmpStartTime = startQuery(); + Query tmpQuery = new Query() + .append(QueryParams.UID.key(), individualUid); + Bson bson = parseQuery(tmpQuery); + List fieldsToInclude = Arrays.asList(QueryParams.ID.key(), QueryParams.UID.key(), QueryParams.VERSION.key(), + QueryParams.STUDY_UID.key()); + // TODO: Quick query simply to obtain the study uid. This should be avoided. The method should already receive the study uid + Document individualDocument = nativeGet(tmpQuery, new QueryOptions(QueryOptions.INCLUDE, fieldsToInclude)).first(); + long studyUid = individualDocument.get(QueryParams.STUDY_UID.key(), Number.class).longValue(); + return versionedMongoDBAdaptor.update(clientSession, bson, fieldsToInclude, entryList -> { + Document individual = entryList.get(0); + String individualId = individual.getString(QueryParams.ID.key()); + + DataResult result = updateAnnotationSets(clientSession, studyUid, individualUid, parameters, variableSetList, + queryOptions, true); + UpdateDocument updateDocument = parseAndValidateUpdateParams(clientSession, parameters, tmpQuery, queryOptions); + Document individualUpdate = updateDocument.toFinalUpdateDocument(); + + if (individualUpdate.isEmpty() && result.getNumUpdated() == 0) { + if (!parameters.isEmpty()) { + logger.error("Non-processed update parameters: {}", parameters.keySet()); + } + throw new CatalogDBException("Nothing to be updated"); + } + + List events = new ArrayList<>(); + if (!individualUpdate.isEmpty()) { + Bson finalQuery = parseQuery(tmpQuery); + + logger.debug("Individual update: query : {}, update: {}", finalQuery.toBsonDocument(), + individualUpdate.toBsonDocument()); + + result = individualCollection.update(clientSession, finalQuery, individualUpdate, new QueryOptions("multi", true)); + + if (result.getNumMatches() == 0) { + throw new CatalogDBException("Individual " + individualId + " not found"); + } + if (result.getNumUpdated() == 0) { + events.add(new Event(Event.Type.WARNING, individualId, "Individual was already updated")); + } + + if (!updateDocument.getAttributes().isEmpty()) { + List addedSamples = updateDocument.getAttributes().getAsLongList("ADDED_SAMPLES"); + List removedSamples = updateDocument.getAttributes().getAsLongList("REMOVED_SAMPLES"); + + // Set new individual reference + dbAdaptorFactory.getCatalogSampleDBAdaptor().updateIndividualFromSampleCollection(clientSession, studyUid, + addedSamples, individualId); + + // Set individual reference to "" + dbAdaptorFactory.getCatalogSampleDBAdaptor().updateIndividualFromSampleCollection(clientSession, studyUid, + removedSamples, ""); + } + + // If the list of disorders or phenotypes is altered, we will need to update the corresponding effective lists + // of the families associated (if any) + if (parameters.containsKey(QueryParams.DISORDERS.key()) || parameters.containsKey(QueryParams.PHENOTYPES.key())) { + recalculateFamilyDisordersPhenotypes(clientSession, studyUid, individualUid); + } + + if (StringUtils.isNotEmpty(parameters.getString(QueryParams.ID.key()))) { + // We need to update the individual id reference in all its samples + dbAdaptorFactory.getCatalogSampleDBAdaptor().updateIndividualIdFromSamples(clientSession, studyUid, + individualId, parameters.getString(QueryParams.ID.key())); + + // Update the family roles + familyDBAdaptor.updateIndividualIdFromFamilies(clientSession, studyUid, individualUid, individualId, + parameters.getString(QueryParams.ID.key())); + } + + if (parameters.containsKey(QueryParams.FATHER_UID.key()) || parameters.containsKey(QueryParams.MOTHER_UID.key())) { + // If the parents have changed, we need to check family roles + recalculateFamilyRolesForMember(clientSession, studyUid, individualUid); + } + + logger.debug("Individual {} successfully updated", individualId); + } + + return endWrite(tmpStartTime, 1, 1, events); + }, Collections.singletonList(QueryParams.SAMPLES_IDS.key()), this::iterator, + (DBIterator iterator) -> updateReferencesAfterIndividualVersionIncrement(clientSession, studyUid, iterator)); } private void recalculateFamilyRolesForMember(ClientSession clientSession, long studyUid, long memberUid) @@ -480,7 +595,7 @@ private void recalculateFamilyRolesForMember(ClientSession clientSession, long s try (DBIterator iterator = familyDBAdaptor.iterator(clientSession, query, options)) { while (iterator.hasNext()) { Family family = iterator.next(); - familyDBAdaptor.privateUpdate(clientSession, family, new ObjectMap(), null, + familyDBAdaptor.transactionalUpdate(clientSession, family, new ObjectMap(), null, new QueryOptions(ParamConstants.FAMILY_UPDATE_ROLES_PARAM, true)); } } @@ -501,18 +616,18 @@ private void updateReferencesAfterIndividualVersionIncrement(ClientSession clien } } - private void recalculateFamilyDisordersPhenotypes(ClientSession clientSession, Individual individual) + private void recalculateFamilyDisordersPhenotypes(ClientSession clientSession, long studyUid, long individualUid) throws CatalogDBException, CatalogParameterException, CatalogAuthorizationException { // We fetch the current updated individual to know how the current list of disorders and phenotypes QueryOptions individualOptions = new QueryOptions(QueryOptions.INCLUDE, Arrays.asList(QueryParams.PHENOTYPES.key(), QueryParams.DISORDERS.key())); Individual currentIndividual = get(clientSession, new Query() - .append(QueryParams.STUDY_UID.key(), individual.getStudyUid()) - .append(QueryParams.UID.key(), individual.getUid()), individualOptions).first(); + .append(QueryParams.STUDY_UID.key(), studyUid) + .append(QueryParams.UID.key(), individualUid), individualOptions).first(); Query familyQuery = new Query() - .append(FamilyDBAdaptor.QueryParams.MEMBER_UID.key(), individual.getUid()) - .append(FamilyDBAdaptor.QueryParams.STUDY_UID.key(), individual.getStudyUid()); + .append(FamilyDBAdaptor.QueryParams.MEMBER_UID.key(), individualUid) + .append(FamilyDBAdaptor.QueryParams.STUDY_UID.key(), studyUid); QueryOptions familyOptions = new QueryOptions(QueryOptions.INCLUDE, Arrays.asList( FamilyDBAdaptor.QueryParams.UID.key(), FamilyDBAdaptor.QueryParams.STUDY_UID.key(), FamilyDBAdaptor.QueryParams.MEMBERS.key())); @@ -530,7 +645,7 @@ private void recalculateFamilyDisordersPhenotypes(ClientSession clientSession, I ObjectMap params = getNewFamilyDisordersAndPhenotypesToUpdate(family, currentIndividual.getDisorders(), currentIndividual.getPhenotypes(), currentIndividual.getUid()); - familyDBAdaptor.privateUpdate(clientSession, family, params, null, familyUpdateOptions); + familyDBAdaptor.transactionalUpdate(clientSession, family, params, null, familyUpdateOptions); } } @@ -625,7 +740,7 @@ private void updateClinicalAnalysisIndividualReferences(ClientSession clientSess ObjectMap params = new ObjectMap(ClinicalAnalysisDBAdaptor.QueryParams.PROBAND.key(), individualCopy); - OpenCGAResult result = dbAdaptorFactory.getClinicalAnalysisDBAdaptor().privateUpdate(clientSession, clinicalAnalysis, + OpenCGAResult result = dbAdaptorFactory.getClinicalAnalysisDBAdaptor().transactionalUpdate(clientSession, clinicalAnalysis, params, Collections.emptyList(), null, QueryOptions.empty()); if (result.getNumUpdated() != 1) { throw new CatalogDBException("ClinicalAnalysis '" + clinicalAnalysis.getId() + "' could not be updated to the latest " @@ -1078,12 +1193,12 @@ public OpenCGAResult get(ClientSession clientSession, Query query, Q } @Override - public OpenCGAResult nativeGet(Query query, QueryOptions options) + public OpenCGAResult nativeGet(Query query, QueryOptions options) throws CatalogDBException, CatalogParameterException, CatalogAuthorizationException { return nativeGet(null, query, options); } - public OpenCGAResult nativeGet(ClientSession clientSession, Query query, QueryOptions options) + public OpenCGAResult nativeGet(ClientSession clientSession, Query query, QueryOptions options) throws CatalogDBException, CatalogParameterException, CatalogAuthorizationException { long startTime = startQuery(); try (DBIterator dbIterator = nativeIterator(clientSession, query, options)) { @@ -1092,12 +1207,12 @@ public OpenCGAResult nativeGet(ClientSession clientSession, Query query, QueryOp } @Override - public OpenCGAResult nativeGet(long studyUid, Query query, QueryOptions options, String user) + public OpenCGAResult nativeGet(long studyUid, Query query, QueryOptions options, String user) throws CatalogDBException, CatalogAuthorizationException, CatalogParameterException { return nativeGet(null, studyUid, query, options, user); } - public OpenCGAResult nativeGet(ClientSession clientSession, long studyUid, Query query, QueryOptions options, String user) + public OpenCGAResult nativeGet(ClientSession clientSession, long studyUid, Query query, QueryOptions options, String user) throws CatalogDBException, CatalogAuthorizationException, CatalogParameterException { long startTime = startQuery(); try (DBIterator dbIterator = nativeIterator(clientSession, studyUid, query, options, user)) { @@ -1669,9 +1784,9 @@ void removeSampleReferences(ClientSession clientSession, long studyUid, long sam QueryOptions queryOptions = new QueryOptions(Constants.ACTIONS, new ObjectMap(QueryParams.SAMPLES.key(), ParamUtils.BasicUpdateAction.REMOVE.name())); - Bson update; + UpdateDocument updateDocument; try { - update = parseAndValidateUpdateParams(clientSession, params, query, queryOptions).toFinalUpdateDocument(); + updateDocument = parseAndValidateUpdateParams(clientSession, params, query, queryOptions); } catch (CatalogDBException e) { if (e.getMessage().contains("No individual found to be updated")) { return; @@ -1681,16 +1796,9 @@ void removeSampleReferences(ClientSession clientSession, long studyUid, long sam } Bson bsonQuery = parseQuery(query); - versionedMongoDBAdaptor.update(clientSession, bsonQuery, () -> { - QueryOptions multi = new QueryOptions(MongoDBCollection.MULTI, true); - logger.debug("Sample references extraction. Query: {}, update: {}", bsonQuery.toBsonDocument(), - update.toBsonDocument()); - DataResult updateResult = individualCollection.update(clientSession, bsonQuery, update, multi); - logger.debug("Sample uid '" + sampleUid + "' references removed from " + updateResult.getNumUpdated() + " out of " - + updateResult.getNumMatches() + " individuals"); - return null; - }, Collections.singletonList(QueryParams.SAMPLES_IDS.key()), this::iterator, - (DBIterator iterator) -> updateReferencesAfterIndividualVersionIncrement(clientSession, studyUid, iterator)); + OpenCGAResult result = transactionalUpdate(clientSession, studyUid, bsonQuery, updateDocument); + logger.debug("Sample uid '" + sampleUid + "' references removed from " + result.getNumUpdated() + " out of " + + result.getNumMatches() + " individuals"); } public MongoDBCollection getIndividualCollection() { diff --git a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/InterpretationMongoDBAdaptor.java b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/InterpretationMongoDBAdaptor.java index 97b1d50546b..af0cc61e95a 100644 --- a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/InterpretationMongoDBAdaptor.java +++ b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/InterpretationMongoDBAdaptor.java @@ -67,7 +67,7 @@ import static org.opencb.opencga.catalog.db.mongodb.ClinicalAnalysisMongoDBAdaptor.fixCommentsForRemoval; import static org.opencb.opencga.catalog.db.mongodb.MongoDBUtils.*; -public class InterpretationMongoDBAdaptor extends MongoDBAdaptor implements InterpretationDBAdaptor { +public class InterpretationMongoDBAdaptor extends CatalogMongoDBAdaptor implements InterpretationDBAdaptor { private final MongoDBCollection interpretationCollection; private final MongoDBCollection archiveInterpretationCollection; @@ -200,7 +200,7 @@ private void updateClinicalAnalysisReferences(ClientSession clientSession, Inter } // Update interpretation(s) in ClinicalAnalysis - clinicalDBAdaptor.privateUpdate(clientSession, ca, params, Collections.emptyList(), clinicalAuditList, options); + clinicalDBAdaptor.transactionalUpdate(clientSession, ca, params, Collections.emptyList(), clinicalAuditList, options); break; case SECONDARY: // Add to secondaryInterpretations array in ClinicalAnalysis @@ -215,7 +215,7 @@ private void updateClinicalAnalysisReferences(ClientSession clientSession, Inter params.put(ClinicalAnalysisDBAdaptor.QueryParams.INTERPRETATION.key(), null); } - clinicalDBAdaptor.privateUpdate(clientSession, ca, params, Collections.emptyList(), clinicalAuditList, options); + clinicalDBAdaptor.transactionalUpdate(clientSession, ca, params, Collections.emptyList(), clinicalAuditList, options); break; default: throw new IllegalStateException("Unknown action " + action); @@ -686,7 +686,7 @@ OpenCGAResult update(ClientSession clientSession, Interpretation if (!updateOperation.isEmpty() || !updateDocument.getNestedUpdateList().isEmpty()) { // Updates to Interpretation data model -> increment version - return versionedMongoDBAdaptor.update(clientSession, bsonQuery, () -> { + return versionedMongoDBAdaptor.update(clientSession, bsonQuery, (entrylist) -> { DataResult update = DataResult.empty(); // Because it will generate a new interpretation version, we set version to +1 so the reference in clinical is also @@ -785,7 +785,7 @@ private void updateClinicalAnalysisInterpretationReference(ClientSession clientS params = new ObjectMap(ClinicalAnalysisDBAdaptor.QueryParams.SECONDARY_INTERPRETATIONS.key(), interpretationList); } - OpenCGAResult update = clinicalDBAdaptor.privateUpdate(clientSession, ca, params, Collections.emptyList(), clinicalAuditList, + OpenCGAResult update = clinicalDBAdaptor.transactionalUpdate(clientSession, ca, params, Collections.emptyList(), clinicalAuditList, options); if (update.getNumUpdated() != 1) { throw new CatalogDBException("Could not update interpretation reference in Clinical Analysis to new version"); @@ -878,7 +878,7 @@ OpenCGAResult delete(ClientSession clientSession, Interpretation interpretation, actions.put(ClinicalAnalysisDBAdaptor.QueryParams.SECONDARY_INTERPRETATIONS.key(), ParamUtils.BasicUpdateAction.REMOVE); clinicalOptions.put(Constants.ACTIONS, actions); } - clinicalDBAdaptor.privateUpdate(clientSession, clinicalAnalysis, clinicalParams, Collections.emptyList(), clinicalAuditList, + clinicalDBAdaptor.transactionalUpdate(clientSession, clinicalAnalysis, clinicalParams, Collections.emptyList(), clinicalAuditList, clinicalOptions); Query query = new Query() diff --git a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/JobMongoDBAdaptor.java b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/JobMongoDBAdaptor.java index 48bedd2acaf..9f201fa9cad 100644 --- a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/JobMongoDBAdaptor.java +++ b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/JobMongoDBAdaptor.java @@ -64,7 +64,7 @@ /** * Created by pfurio on 08/01/16. */ -public class JobMongoDBAdaptor extends MongoDBAdaptor implements JobDBAdaptor { +public class JobMongoDBAdaptor extends CatalogMongoDBAdaptor implements JobDBAdaptor { private static final String PRIVATE_PRIORITY = "_priority"; private static final String PRIVATE_STUDY_UIDS = "_studyUids"; diff --git a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/MongoDBAdaptor.java b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/MongoDBAdaptor.java index a3b47c037dc..0c577c0a9da 100644 --- a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/MongoDBAdaptor.java +++ b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/MongoDBAdaptor.java @@ -45,7 +45,7 @@ /** * Created by jacobo on 12/09/14. */ -public class MongoDBAdaptor extends AbstractDBAdaptor { +public abstract class MongoDBAdaptor extends AbstractDBAdaptor { public static final String PRIVATE_UID = "uid"; public static final String PRIVATE_UUID = "uuid"; diff --git a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/PanelMongoDBAdaptor.java b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/PanelMongoDBAdaptor.java index 35b290c064d..9ad5b57fccf 100644 --- a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/PanelMongoDBAdaptor.java +++ b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/PanelMongoDBAdaptor.java @@ -55,7 +55,7 @@ import static org.opencb.opencga.catalog.db.mongodb.MongoDBUtils.*; -public class PanelMongoDBAdaptor extends MongoDBAdaptor implements PanelDBAdaptor { +public class PanelMongoDBAdaptor extends CatalogMongoDBAdaptor implements PanelDBAdaptor { private final MongoDBCollection panelCollection; private final MongoDBCollection panelArchiveCollection; @@ -326,7 +326,7 @@ public OpenCGAResult update(Query query, ObjectMap parameters, QueryOptions quer return result; } - private OpenCGAResult privateUpdate(ClientSession clientSession, Panel panel, ObjectMap parameters, QueryOptions queryOptions) + private OpenCGAResult privateUpdate(ClientSession clientSession, Panel panel, ObjectMap parameters, QueryOptions queryOptions) throws CatalogDBException, CatalogParameterException, CatalogAuthorizationException { long tmpStartTime = startQuery(); Query tmpQuery = new Query() @@ -343,7 +343,7 @@ private OpenCGAResult privateUpdate(ClientSession clientSession, Panel p } Bson finalQuery = parseQuery(tmpQuery); - return versionedMongoDBAdaptor.update(clientSession, finalQuery, () -> { + return versionedMongoDBAdaptor.update(clientSession, finalQuery, (entrylist) -> { logger.debug("Panel update: query : {}, update: {}", finalQuery.toBsonDocument(), panelUpdate.toBsonDocument()); DataResult result = panelCollection.update(clientSession, finalQuery, new Document("$set", panelUpdate), diff --git a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/ProjectMongoDBAdaptor.java b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/ProjectMongoDBAdaptor.java index 1474f1ed4e1..85304c18e71 100644 --- a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/ProjectMongoDBAdaptor.java +++ b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/ProjectMongoDBAdaptor.java @@ -60,7 +60,7 @@ /** * Created by imedina on 08/01/16. */ -public class ProjectMongoDBAdaptor extends MongoDBAdaptor implements ProjectDBAdaptor { +public class ProjectMongoDBAdaptor extends CatalogMongoDBAdaptor implements ProjectDBAdaptor { private final MongoDBCollection userCollection; private final MongoDBCollection deletedUserCollection; @@ -604,7 +604,7 @@ public OpenCGAResult get(Query query, QueryOptions options, String user } @Override - public OpenCGAResult nativeGet(Query query, QueryOptions options) throws CatalogDBException { + public OpenCGAResult nativeGet(Query query, QueryOptions options) throws CatalogDBException { long startTime = startQuery(); try (DBIterator dbIterator = nativeIterator(query, options)) { return endQuery(startTime, dbIterator); diff --git a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/SampleMongoDBAdaptor.java b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/SampleMongoDBAdaptor.java index 22ffb20c77e..da6dca117ab 100644 --- a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/SampleMongoDBAdaptor.java +++ b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/SampleMongoDBAdaptor.java @@ -21,7 +21,6 @@ import com.mongodb.client.model.Aggregates; import com.mongodb.client.model.Filters; import com.mongodb.client.model.Projections; -import com.mongodb.client.model.Updates; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.NotImplementedException; import org.apache.commons.lang3.StringUtils; @@ -63,6 +62,7 @@ import java.util.concurrent.TimeUnit; import java.util.function.Consumer; import java.util.function.UnaryOperator; +import java.util.stream.Collectors; import static org.opencb.opencga.catalog.db.api.ClinicalAnalysisDBAdaptor.QueryParams.MODIFICATION_DATE; import static org.opencb.opencga.catalog.db.mongodb.AuthorizationMongoDBUtils.filterAnnotationSets; @@ -83,10 +83,6 @@ public class SampleMongoDBAdaptor extends AnnotationMongoDBAdaptor imple private final IndividualMongoDBAdaptor individualDBAdaptor; private final VersionedMongoDBAdaptor versionedMongoDBAdaptor; - final QueryOptions SAMPLE_FETCH_FOR_UPDATE_OPTIONS = new QueryOptions(QueryOptions.INCLUDE, - Arrays.asList(QueryParams.ID.key(), QueryParams.UID.key(), QueryParams.VERSION.key(), QueryParams.STUDY_UID.key(), - PRIVATE_INDIVIDUAL_UID)); - public SampleMongoDBAdaptor(MongoDBCollection sampleCollection, MongoDBCollection archiveSampleCollection, MongoDBCollection deletedSampleCollection, Configuration configuration, MongoDBAdaptorFactory dbAdaptorFactory) { @@ -253,7 +249,10 @@ public OpenCGAResult update(long id, ObjectMap parameters, QueryOptions queryOpt public OpenCGAResult update(long uid, ObjectMap parameters, List variableSetList, QueryOptions queryOptions) throws CatalogDBException, CatalogParameterException, CatalogAuthorizationException { Query query = new Query(QueryParams.UID.key(), uid); - OpenCGAResult documentResult = nativeGet(query, SAMPLE_FETCH_FOR_UPDATE_OPTIONS); + QueryOptions options = new QueryOptions(QueryOptions.INCLUDE, + Arrays.asList(QueryParams.ID.key(), QueryParams.UID.key(), QueryParams.VERSION.key(), QueryParams.STUDY_UID.key(), + PRIVATE_INDIVIDUAL_UID)); + OpenCGAResult documentResult = nativeGet(query, options); if (documentResult.getNumResults() == 0) { throw new CatalogDBException("Could not update sample. Sample uid '" + uid + "' not found."); } @@ -307,7 +306,7 @@ public OpenCGAResult update(Query query, ObjectMap parameters, List return result; } - OpenCGAResult privateUpdate(ClientSession clientSession, Document sampleDocument, ObjectMap parameters, + OpenCGAResult privateUpdate(ClientSession clientSession, Document sampleDocument, ObjectMap parameters, List variableSetList, QueryOptions queryOptions) throws CatalogDBException, CatalogParameterException, CatalogAuthorizationException { long tmpStartTime = startQuery(); @@ -320,9 +319,9 @@ OpenCGAResult privateUpdate(ClientSession clientSession, Document sample .append(QueryParams.STUDY_UID.key(), studyUid) .append(QueryParams.UID.key(), sampleUid); Bson bsonQuery = parseQuery(tmpQuery); - return versionedMongoDBAdaptor.update(clientSession, bsonQuery, () -> { + return versionedMongoDBAdaptor.update(clientSession, bsonQuery, (entrylist) -> { // Perform the update - DataResult result = updateAnnotationSets(clientSession, sampleUid, parameters, variableSetList, queryOptions, true); + DataResult result = updateAnnotationSets(clientSession, studyUid, sampleUid, parameters, variableSetList, queryOptions, true); UpdateDocument updateParams = parseAndValidateUpdateParams(clientSession, studyUid, parameters, tmpQuery, queryOptions); Document sampleUpdate = updateParams.toFinalUpdateDocument(); @@ -342,21 +341,104 @@ OpenCGAResult privateUpdate(ClientSession clientSession, Document sample result = sampleCollection.update(clientSession, finalQuery, sampleUpdate, new QueryOptions(MongoDBCollection.MULTI, true)); if (updateParams.getSet().containsKey(PRIVATE_INDIVIDUAL_UID)) { - long individualUid = sampleDocument.getLong(PRIVATE_INDIVIDUAL_UID); + long oldIndividualUid = sampleDocument.getLong(PRIVATE_INDIVIDUAL_UID); long newIndividualUid = updateParams.getSet().getLong(PRIVATE_INDIVIDUAL_UID); // If the sample has been associated a different individual - if (newIndividualUid != individualUid) { + if (newIndividualUid != oldIndividualUid) { Sample sample = new Sample().setUid(sampleUid).setVersion(version).setStudyUid(studyUid); + if (oldIndividualUid > 0) { + // Remove the sample from the individual where it was associated + updateSampleFromIndividualCollection(clientSession, sample, oldIndividualUid, + ParamUtils.BasicUpdateAction.REMOVE); + } if (newIndividualUid > 0) { // Add the sample to the list of samples of new individual updateSampleFromIndividualCollection(clientSession, sample, newIndividualUid, ParamUtils.BasicUpdateAction.ADD); } + } + } + + if (result.getNumMatches() == 0) { + throw new CatalogDBException("Sample " + sampleId + " not found"); + } + if (result.getNumUpdated() == 0) { + events.add(new Event(Event.Type.WARNING, sampleId, "Sample was already updated")); + } + logger.debug("Sample {} successfully updated", sampleId); + } + + return endWrite(tmpStartTime, 1, 1, events); + }, this::iterator, (DBIterator iterator) -> updateReferencesAfterSampleVersionIncrement(clientSession, iterator)); + } + + @Override + OpenCGAResult transactionalUpdate(ClientSession clientSession, Sample sample, ObjectMap parameters, + List variableSetList, QueryOptions queryOptions) + throws CatalogParameterException, CatalogDBException, CatalogAuthorizationException { + long tmpStartTime = startQuery(); + long studyUid = sample.getStudyUid(); + long sampleUid = sample.getUid(); + if (studyUid <= 0) { + throw new CatalogDBException("Unexpected studyUid value received"); + } + if (sampleUid <= 0) { + throw new CatalogDBException("Unexpected sampleUid value received"); + } + + Query tmpQuery = new Query() + .append(QueryParams.STUDY_UID.key(), studyUid) + .append(QueryParams.UID.key(), sampleUid); + List fieldsToInclude = Arrays.asList(QueryParams.ID.key(), QueryParams.UID.key(), QueryParams.VERSION.key(), + QueryParams.STUDY_UID.key(), PRIVATE_INDIVIDUAL_UID); + + Bson bsonQuery = parseQuery(tmpQuery); + return versionedMongoDBAdaptor.update(clientSession, bsonQuery, fieldsToInclude, (entrylist) -> { + String sampleId = entrylist.get(0).getString(QueryParams.ID.key()); + // Perform the update + DataResult result = updateAnnotationSets(clientSession, studyUid, sampleUid, parameters, variableSetList, queryOptions, + true); + + UpdateDocument updateParams = parseAndValidateUpdateParams(clientSession, studyUid, parameters, tmpQuery, queryOptions); + Document sampleUpdate = updateParams.toFinalUpdateDocument(); + + if (sampleUpdate.isEmpty() && result.getNumUpdated() == 0) { + if (!parameters.isEmpty()) { + logger.error("Non-processed update parameters: {}", parameters.keySet()); + } + throw new CatalogDBException("Nothing to be updated"); + } + + List events = new ArrayList<>(); + if (!sampleUpdate.isEmpty()) { + Bson finalQuery = parseQuery(tmpQuery); + + logger.debug("Sample update: query : {}, update: {}", finalQuery.toBsonDocument(), sampleUpdate.toBsonDocument()); + result = sampleCollection.update(clientSession, finalQuery, sampleUpdate, new QueryOptions(MongoDBCollection.MULTI, true)); + + if (updateParams.getSet().containsKey(PRIVATE_INDIVIDUAL_UID)) { + long individualUid = entrylist.get(0).getLong(PRIVATE_INDIVIDUAL_UID); + long newIndividualUid = updateParams.getSet().getLong(PRIVATE_INDIVIDUAL_UID); + + // If the sample has been associated a different individual + if (newIndividualUid != individualUid) { + int version = entrylist.get(0).getInteger(QueryParams.VERSION.key()); + Sample tmpSample = new Sample() + .setUid(sampleUid) + .setVersion(version) + .setStudyUid(studyUid); + + if (newIndividualUid > 0) { + // Add the sample to the list of samples of new individual + updateSampleFromIndividualCollection(clientSession, tmpSample, newIndividualUid, + ParamUtils.BasicUpdateAction.ADD); + } if (individualUid > 0) { // Remove the sample from the individual where it was associated - updateSampleFromIndividualCollection(clientSession, sample, individualUid, ParamUtils.BasicUpdateAction.REMOVE); + updateSampleFromIndividualCollection(clientSession, tmpSample, individualUid, + ParamUtils.BasicUpdateAction.REMOVE); } } } @@ -374,6 +456,32 @@ OpenCGAResult privateUpdate(ClientSession clientSession, Document sample }, this::iterator, (DBIterator iterator) -> updateReferencesAfterSampleVersionIncrement(clientSession, iterator)); } + @Override + OpenCGAResult transactionalUpdate(ClientSession clientSession, long studyUid, Bson query, UpdateDocument updateDocument) + throws CatalogParameterException, CatalogDBException, CatalogAuthorizationException { + long tmpStartTime = startQuery(); + + List includeIds = Arrays.asList(QueryParams.ID.key(), QueryParams.UID.key(), QueryParams.VERSION.key(), + QueryParams.STUDY_UID.key(), PRIVATE_INDIVIDUAL_UID); + return versionedMongoDBAdaptor.update(clientSession, query, includeIds, (sampleList) -> { + List events = new ArrayList<>(); + Document update = updateDocument.toFinalUpdateDocument(); + if (!update.isEmpty()) { + logger.debug("Sample update: query : {}, update: {}", query.toBsonDocument(), update.toBsonDocument()); + DataResult result = sampleCollection.update(clientSession, query, update, + new QueryOptions(MongoDBCollection.MULTI, true)); + List sampleIds = sampleList.stream().map(x -> x.getString(QueryParams.ID.key())).collect(Collectors.toList()); + if (result.getNumUpdated() == 0) { + for (String sampleId : sampleIds) { + events.add(new Event(Event.Type.WARNING, sampleId, "Sample was already updated")); + } + } + logger.debug("Samples {} successfully updated", StringUtils.join(sampleIds, ", ")); + } + return endWrite(tmpStartTime, sampleList.size(), sampleList.size(), events); + }, this::iterator, (DBIterator iterator) -> updateReferencesAfterSampleVersionIncrement(clientSession, iterator)); + } + private void updateReferencesAfterSampleVersionIncrement(ClientSession clientSession, DBIterator iterator) throws CatalogParameterException, CatalogDBException, CatalogAuthorizationException { while (iterator.hasNext()) { @@ -388,28 +496,25 @@ void updateIndividualFromSampleCollection(ClientSession clientSession, long stud } ObjectMap params = new ObjectMap(QueryParams.INDIVIDUAL_ID.key(), individualId); - Document update = parseAndValidateUpdateParams(clientSession, studyId, params, null, QueryOptions.empty()).toFinalUpdateDocument(); + UpdateDocument updateDocument = parseAndValidateUpdateParams(clientSession, studyId, params, null, QueryOptions.empty()); Bson query = parseQuery(new Query() .append(QueryParams.STUDY_UID.key(), studyId) .append(QueryParams.UID.key(), sampleUids)); - versionedMongoDBAdaptor.update(clientSession, query, () -> { - QueryOptions options = new QueryOptions(MongoDBCollection.MULTI, true); - return sampleCollection.update(clientSession, query, update, options); - }, this::iterator, (DBIterator iterator) -> updateReferencesAfterSampleVersionIncrement(clientSession, iterator)); + transactionalUpdate(clientSession, studyId, query, updateDocument); } void updateCohortReferences(ClientSession clientSession, long studyUid, List sampleUids, String cohortId, ParamUtils.BasicUpdateAction action) throws CatalogParameterException, CatalogDBException, CatalogAuthorizationException { - Bson bsonUpdate; + UpdateDocument updateDocument = new UpdateDocument(); switch (action) { case ADD: - bsonUpdate = Updates.addToSet(SampleDBAdaptor.QueryParams.COHORT_IDS.key(), cohortId); + updateDocument.getAddToSet().put(SampleDBAdaptor.QueryParams.COHORT_IDS.key(), cohortId); break; case REMOVE: - bsonUpdate = Updates.pull(SampleDBAdaptor.QueryParams.COHORT_IDS.key(), cohortId); + updateDocument.getPull().put(SampleDBAdaptor.QueryParams.COHORT_IDS.key(), cohortId); break; case SET: default: @@ -421,14 +526,7 @@ void updateCohortReferences(ClientSession clientSession, long studyUid, List { - DataResult update = sampleCollection.update(clientSession, bsonQuery, bsonUpdate, - new QueryOptions(MongoDBCollection.MULTI, true)); - if (update.getNumMatches() == 0) { - throw new CatalogDBException("Could not update cohort references in samples"); - } - return update; - }, this::iterator, (DBIterator iterator) -> updateReferencesAfterSampleVersionIncrement(clientSession, iterator)); + transactionalUpdate(clientSession, studyUid, bsonQuery, updateDocument); } /** @@ -466,8 +564,8 @@ private void updateIndividualSampleReferences(ClientSession clientSession, Sampl options = new QueryOptions() .append(Constants.ACTIONS, action); - OpenCGAResult result = dbAdaptorFactory.getCatalogIndividualDBAdaptor().privateUpdate(clientSession, individual, params, null, - options); + OpenCGAResult result = dbAdaptorFactory.getCatalogIndividualDBAdaptor().transactionalUpdate(clientSession, individual, + params, null, options); if (result.getNumUpdated() != 1) { throw new CatalogDBException("Individual '" + individual.getId() + "' could not be updated to the latest sample version" + " of '" + sample.getId() + "'"); @@ -489,11 +587,10 @@ void updateIndividualIdFromSamples(ClientSession clientSession, long studyUid, S .append(QueryParams.INDIVIDUAL_ID.key(), oldIndividualId); Bson bsonQuery = parseQuery(query); - Bson update = Updates.set(QueryParams.INDIVIDUAL_ID.key(), newIndividualId); + UpdateDocument updateDocument = new UpdateDocument(); + updateDocument.getSet().put(QueryParams.INDIVIDUAL_ID.key(), newIndividualId); - versionedMongoDBAdaptor.update(clientSession, bsonQuery, - () -> sampleCollection.update(clientSession, bsonQuery, update, new QueryOptions(MongoDBCollection.MULTI, true)), - this::iterator, (DBIterator iterator) -> updateReferencesAfterSampleVersionIncrement(clientSession, iterator)); + transactionalUpdate(clientSession, studyUid, bsonQuery, updateDocument); } /** @@ -528,13 +625,9 @@ private void updateSampleFromIndividualCollection(ClientSession clientSession, S actionMap.put(IndividualDBAdaptor.QueryParams.SAMPLES.key(), updateAction.name()); options.put(Constants.ACTIONS, actionMap); - Query query = new Query(IndividualDBAdaptor.QueryParams.UID.key(), individualUid); - Document update = individualDBAdaptor.parseAndValidateUpdateParams(clientSession, params, query, options).toFinalUpdateDocument(); - Bson bsonQuery = individualDBAdaptor.parseQuery(new Query() - .append(IndividualDBAdaptor.QueryParams.UID.key(), individualUid) - .append(IndividualDBAdaptor.QueryParams.STUDY_UID.key(), sample.getStudyUid()), null); - - individualDBAdaptor.getCollection().update(clientSession, bsonQuery, update, null); + Individual individual = new Individual().setUid(individualUid) + .setStudyUid(sample.getStudyUid()); + individualDBAdaptor.transactionalUpdate(clientSession, individual, params, null, options); } UpdateDocument parseAndValidateUpdateParams(ClientSession clientSession, long studyUid, ObjectMap parameters, Query query, @@ -782,14 +875,8 @@ public OpenCGAResult setRgaIndexes(long studyUid, List sampleUids, Bson query = Filters.and(filters); UpdateDocument updateDocument = new UpdateDocument().setSet(rootDocument); - Document bsonUpdate = updateDocument.toFinalUpdateDocument(); - - return runTransaction( - (ClientSession clientSession) -> versionedMongoDBAdaptor.update(clientSession, query, - () -> new OpenCGAResult<>(sampleCollection.update(query, bsonUpdate, new QueryOptions("multi", true))), - this::iterator, - (DBIterator iterator) -> updateReferencesAfterSampleVersionIncrement(clientSession, iterator))); + return runTransaction(session -> transactionalUpdate(session, studyUid, query, updateDocument)); } @Override @@ -932,11 +1019,8 @@ void removeFileReferences(ClientSession clientSession, long studyUid, String fil logger.debug("Removing file from sample '{}' field. Query: {}, Update: {}", QueryParams.FILE_IDS.key(), bsonQuery.toBsonDocument(), updateDocument.toBsonDocument()); - versionedMongoDBAdaptor.update(clientSession, bsonQuery, () -> { - DataResult result = sampleCollection.update(clientSession, bsonQuery, updateDocument, new QueryOptions("multi", true)); - logger.debug("File '{}' removed from {} samples", fileId, result.getNumUpdated()); - return result; - }, this::iterator, (DBIterator iterator) -> updateReferencesAfterSampleVersionIncrement(clientSession, iterator)); + OpenCGAResult result = transactionalUpdate(clientSession, studyUid, bsonQuery, document); + logger.debug("File '{}' removed from {} samples", fileId, result.getNumUpdated()); } // TODO: Check clean diff --git a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/StudyMongoDBAdaptor.java b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/StudyMongoDBAdaptor.java index d1648813ee8..b0d67dc923a 100644 --- a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/StudyMongoDBAdaptor.java +++ b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/StudyMongoDBAdaptor.java @@ -71,7 +71,7 @@ * * @author Jacobo Coll <jacobo167@gmail.com> */ -public class StudyMongoDBAdaptor extends MongoDBAdaptor implements StudyDBAdaptor { +public class StudyMongoDBAdaptor extends CatalogMongoDBAdaptor implements StudyDBAdaptor { private final MongoDBCollection studyCollection; private final MongoDBCollection deletedStudyCollection; @@ -863,8 +863,8 @@ public OpenCGAResult createVariableSet(long studyId, VariableSet va } @Override - public OpenCGAResult addFieldToVariableSet(long variableSetId, Variable variable, String user) - throws CatalogDBException, CatalogAuthorizationException { + public OpenCGAResult addFieldToVariableSet(long studyUid, long variableSetId, Variable variable, String user) + throws CatalogDBException, CatalogAuthorizationException, CatalogParameterException { OpenCGAResult variableSet = getVariableSet(variableSetId, new QueryOptions(), user); checkVariableNotInVariableSet(variableSet.first(), variable.getId()); @@ -876,11 +876,12 @@ public OpenCGAResult addFieldToVariableSet(long variableSetId, Vari throw CatalogDBException.updateError("VariableSet", variableSetId); } if (variable.isRequired()) { - dbAdaptorFactory.getCatalogSampleDBAdaptor().addVariableToAnnotations(variableSetId, variable); - dbAdaptorFactory.getCatalogCohortDBAdaptor().addVariableToAnnotations(variableSetId, variable); - dbAdaptorFactory.getCatalogIndividualDBAdaptor().addVariableToAnnotations(variableSetId, variable); - dbAdaptorFactory.getCatalogFamilyDBAdaptor().addVariableToAnnotations(variableSetId, variable); - dbAdaptorFactory.getCatalogFileDBAdaptor().addVariableToAnnotations(variableSetId, variable); + dbAdaptorFactory.getCatalogSampleDBAdaptor().addVariableToAnnotations(studyUid, variableSetId, variable); + dbAdaptorFactory.getCatalogCohortDBAdaptor().addVariableToAnnotations(studyUid, variableSetId, variable); + dbAdaptorFactory.getCatalogIndividualDBAdaptor().addVariableToAnnotations(studyUid, variableSetId, variable); + dbAdaptorFactory.getCatalogFamilyDBAdaptor().addVariableToAnnotations(studyUid, variableSetId, variable); + dbAdaptorFactory.getCatalogFileDBAdaptor().addVariableToAnnotations(studyUid, variableSetId, variable); + dbAdaptorFactory.getClinicalAnalysisDBAdaptor().addVariableToAnnotations(studyUid, variableSetId, variable); } return new OpenCGAResult<>(result); @@ -939,8 +940,8 @@ public OpenCGAResult renameFieldVariableSet(long variableSetId, Str } @Override - public OpenCGAResult removeFieldFromVariableSet(long variableSetId, String name, String user) - throws CatalogDBException, CatalogAuthorizationException { + public OpenCGAResult removeFieldFromVariableSet(long studyUid, long variableSetId, String name, String user) + throws CatalogDBException, CatalogAuthorizationException, CatalogParameterException { long startTime = startQuery(); OpenCGAResult variableSet = getVariableSet(variableSetId, new QueryOptions(), user); @@ -956,11 +957,12 @@ public OpenCGAResult removeFieldFromVariableSet(long variableSetId, } // Remove all the annotations from that field - dbAdaptorFactory.getCatalogSampleDBAdaptor().removeAnnotationField(variableSetId, name); - dbAdaptorFactory.getCatalogCohortDBAdaptor().removeAnnotationField(variableSetId, name); - dbAdaptorFactory.getCatalogIndividualDBAdaptor().removeAnnotationField(variableSetId, name); - dbAdaptorFactory.getCatalogFamilyDBAdaptor().removeAnnotationField(variableSetId, name); - dbAdaptorFactory.getCatalogFileDBAdaptor().removeAnnotationField(variableSetId, name); + dbAdaptorFactory.getCatalogSampleDBAdaptor().removeAnnotationField(studyUid, variableSetId, name); + dbAdaptorFactory.getCatalogCohortDBAdaptor().removeAnnotationField(studyUid, variableSetId, name); + dbAdaptorFactory.getCatalogIndividualDBAdaptor().removeAnnotationField(studyUid, variableSetId, name); + dbAdaptorFactory.getCatalogFamilyDBAdaptor().removeAnnotationField(studyUid, variableSetId, name); + dbAdaptorFactory.getCatalogFileDBAdaptor().removeAnnotationField(studyUid, variableSetId, name); + dbAdaptorFactory.getClinicalAnalysisDBAdaptor().removeAnnotationField(studyUid, variableSetId, name); return new OpenCGAResult<>(result); } @@ -1234,7 +1236,7 @@ public OpenCGAResult deleteVariableSet(long studyUid, VariableSet v } private void deleteAllAnnotationSetsByVariableSet(ClientSession session, long studyUid, VariableSet variableSet) - throws CatalogDBException { + throws CatalogDBException, CatalogParameterException, CatalogAuthorizationException { List entities = variableSet.getEntities(); if (CollectionUtils.isEmpty(entities)) { entities = new ArrayList<>(EnumSet.allOf(VariableSet.AnnotableDataModels.class)); diff --git a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/UserMongoDBAdaptor.java b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/UserMongoDBAdaptor.java index a25d2eabd10..0ba4f454192 100644 --- a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/UserMongoDBAdaptor.java +++ b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/UserMongoDBAdaptor.java @@ -65,7 +65,7 @@ /** * @author Jacobo Coll <jacobo167@gmail.com> */ -public class UserMongoDBAdaptor extends MongoDBAdaptor implements UserDBAdaptor { +public class UserMongoDBAdaptor extends CatalogMongoDBAdaptor implements UserDBAdaptor { private final MongoDBCollection userCollection; private final MongoDBCollection deletedUserCollection; diff --git a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/VersionedMongoDBAdaptor.java b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/VersionedMongoDBAdaptor.java index abafe45bf38..11318fe3fd9 100644 --- a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/VersionedMongoDBAdaptor.java +++ b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/VersionedMongoDBAdaptor.java @@ -16,6 +16,7 @@ import org.opencb.opencga.catalog.exceptions.CatalogDBException; import org.opencb.opencga.catalog.exceptions.CatalogParameterException; import org.opencb.opencga.core.models.common.InternalStatus; +import org.opencb.opencga.core.response.OpenCGAResult; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -117,6 +118,10 @@ private String getClientSessionUuid(ClientSession session) { } public interface VersionedModelExecution { + T execute(List entries) throws CatalogDBException, CatalogAuthorizationException, CatalogParameterException; + } + + public interface NonVersionedModelExecution { T execute() throws CatalogDBException, CatalogAuthorizationException, CatalogParameterException; } @@ -137,29 +142,46 @@ protected void insert(ClientSession session, Document document) { archiveCollection.insert(session, document, QueryOptions.empty()); } - protected T update(ClientSession session, Bson sourceQuery, VersionedModelExecution update, - PostVersionIncrementIterator postVersionIncrementIterator, - ReferenceModelExecution postVersionIncrementExecution) + protected OpenCGAResult update(ClientSession session, Bson sourceQuery, VersionedModelExecution> update, + PostVersionIncrementIterator postVersionIncrementIterator, + ReferenceModelExecution postVersionIncrementExecution) + throws CatalogDBException, CatalogParameterException, CatalogAuthorizationException { + return update(session, sourceQuery, Collections.emptyList(), update, Collections.emptyList(), postVersionIncrementIterator, + postVersionIncrementExecution); + } + + protected OpenCGAResult update(ClientSession session, Bson sourceQuery, List fieldsToInclude, + VersionedModelExecution> update, PostVersionIncrementIterator postVersionIncrementIterator, + ReferenceModelExecution postVersionIncrementExecution) throws CatalogDBException, CatalogParameterException, CatalogAuthorizationException { - return update(session, sourceQuery, update, Collections.emptyList(), postVersionIncrementIterator, postVersionIncrementExecution); + return update(session, sourceQuery, fieldsToInclude, update, Collections.emptyList(), postVersionIncrementIterator, + postVersionIncrementExecution); } - protected T update(ClientSession session, Bson sourceQuery, VersionedModelExecution update, - List postVersionIncrementAdditionalIncludeFields, PostVersionIncrementIterator dbIterator, - ReferenceModelExecution postVersionIncrementExecution) + protected OpenCGAResult update(ClientSession session, Bson sourceQuery, List fieldsToInclude, + VersionedModelExecution> update, + List postVersionIncrementAdditionalIncludeFields, + PostVersionIncrementIterator dbIterator, + ReferenceModelExecution postVersionIncrementExecution) throws CatalogDBException, CatalogParameterException, CatalogAuthorizationException { String uuid = getClientSessionUuid(session); // 1. Increment version // 1.1 Only increase version of those documents not already increased by same transaction id - QueryOptions options = new QueryOptions(QueryOptions.INCLUDE, - Arrays.asList(PRIVATE_UID, VERSION, RELEASE_FROM_VERSION, PRIVATE_TRANSACTION_ID)); + Set includeFields = new HashSet<>(Arrays.asList(PRIVATE_UID, VERSION, RELEASE_FROM_VERSION, PRIVATE_TRANSACTION_ID)); + if (fieldsToInclude != null) { + includeFields.addAll(fieldsToInclude); + } + QueryOptions options = new QueryOptions(QueryOptions.INCLUDE, includeFields); + List entryList = new LinkedList<>(); List allUids = new LinkedList<>(); List uidsChanged = new LinkedList<>(); try (MongoDBIterator iterator = collection.iterator(session, sourceQuery, null, null, options)) { while (iterator.hasNext()) { Document result = iterator.next(); + entryList.add(result); + long uid = result.get(PRIVATE_UID, Number.class).longValue(); int version = result.get(VERSION, Number.class).intValue(); String transactionId = result.getString(PRIVATE_TRANSACTION_ID); @@ -192,8 +214,13 @@ protected T update(ClientSession session, Bson sourceQuery, VersionedMode } } + if (entryList.isEmpty()) { + logger.warn("Update not executed. No entries could be found for query '{}'", sourceQuery.toBsonDocument()); + return OpenCGAResult.empty(); + } + // 2. Execute main update - T executionResult = update.execute(); + OpenCGAResult executionResult = update.execute(entryList); // 3. Fetch document containing update and copy into the archive collection Bson bsonQuery = Filters.in(PRIVATE_UID, allUids); @@ -245,7 +272,7 @@ protected T update(ClientSession session, Bson sourceQuery, VersionedMode return executionResult; } - protected T updateWithoutVersionIncrement(Bson sourceQuery, VersionedModelExecution update) + protected T updateWithoutVersionIncrement(Bson sourceQuery, NonVersionedModelExecution update) throws CatalogDBException, CatalogParameterException, CatalogAuthorizationException { // Execute main update T executionResult = update.execute(); diff --git a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/converters/SampleConverter.java b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/converters/SampleConverter.java index 582509ad581..20ca29506c6 100644 --- a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/converters/SampleConverter.java +++ b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/converters/SampleConverter.java @@ -49,7 +49,6 @@ public Document convertToStorageType(Sample object, List variableSe document.put("uid", object.getUid()); document.put("studyUid", object.getStudyUid()); - document.put("individual", new Document()); return document; } diff --git a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/managers/FileManager.java b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/managers/FileManager.java index d7cbd3cc475..3d643c17bb2 100644 --- a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/managers/FileManager.java +++ b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/managers/FileManager.java @@ -1558,7 +1558,7 @@ public OpenCGAResult delete(String studyStr, List fileIds, ObjectMap par boolean physicalDelete = params.getBoolean(Constants.SKIP_TRASH, false); auditManager.initAuditBatch(operationUuid); - OpenCGAResult result = OpenCGAResult.empty(); + OpenCGAResult result = OpenCGAResult.empty(File.class); for (String id : fileIds) { String fileId = id; String fileUuid = ""; diff --git a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/managers/StudyManager.java b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/managers/StudyManager.java index 184bbe18b67..9c22e95f0bd 100644 --- a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/managers/StudyManager.java +++ b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/managers/StudyManager.java @@ -1429,7 +1429,7 @@ public OpenCGAResult addFieldToVariableSet(String studyId, String v } authorizationManager.checkCanCreateUpdateDeleteVariableSets(study.getUid(), userId); - OpenCGAResult result = studyDBAdaptor.addFieldToVariableSet(variableSet.getUid(), variable, userId); + OpenCGAResult result = studyDBAdaptor.addFieldToVariableSet(study.getUid(), variableSet.getUid(), variable, userId); auditManager.audit(userId, Enums.Action.ADD_VARIABLE_TO_VARIABLE_SET, Enums.Resource.STUDY, variableSet.getId(), "", study.getId(), study.getUuid(), auditParams, new AuditRecord.Status(AuditRecord.Status.Result.SUCCESS)); @@ -1457,7 +1457,7 @@ public OpenCGAResult removeFieldFromVariableSet(String studyId, Str try { authorizationManager.checkCanCreateUpdateDeleteVariableSets(study.getUid(), userId); - OpenCGAResult result = studyDBAdaptor.removeFieldFromVariableSet(variableSet.getUid(), variableId, userId); + OpenCGAResult result = studyDBAdaptor.removeFieldFromVariableSet(study.getUid(), variableSet.getUid(), variableId, userId); auditManager.audit(userId, Enums.Action.REMOVE_VARIABLE_FROM_VARIABLE_SET, Enums.Resource.STUDY, variableSet.getId(), "", study.getId(), study.getUuid(), auditParams, new AuditRecord.Status(AuditRecord.Status.Result.SUCCESS)); diff --git a/opencga-catalog/src/test/java/org/opencb/opencga/catalog/db/mongodb/StudyMongoDBAdaptorTest.java b/opencga-catalog/src/test/java/org/opencb/opencga/catalog/db/mongodb/StudyMongoDBAdaptorTest.java index 5791005394c..480866110ae 100644 --- a/opencga-catalog/src/test/java/org/opencb/opencga/catalog/db/mongodb/StudyMongoDBAdaptorTest.java +++ b/opencga-catalog/src/test/java/org/opencb/opencga/catalog/db/mongodb/StudyMongoDBAdaptorTest.java @@ -100,10 +100,10 @@ public void createVariableSetTest() throws CatalogDBException { } @Test - public void testRemoveFieldFromVariableSet() throws CatalogDBException, CatalogAuthorizationException { + public void testRemoveFieldFromVariableSet() throws CatalogDBException, CatalogAuthorizationException, CatalogParameterException { DataResult variableSetDataResult = createExampleVariableSet("VARSET_1", false); DataResult result = - catalogStudyDBAdaptor.removeFieldFromVariableSet(variableSetDataResult.first().getUid(), "NAME", user3.getId()); + catalogStudyDBAdaptor.removeFieldFromVariableSet(5L, variableSetDataResult.first().getUid(), "NAME", user3.getId()); assertEquals(1, result.getNumUpdated()); VariableSet variableSet = catalogStudyDBAdaptor.getVariableSet(variableSetDataResult.first().getUid(), QueryOptions.empty()).first(); @@ -153,12 +153,12 @@ public void testRemoveFieldFromVariableSet() throws CatalogDBException, CatalogA * @throws CatalogDBException */ @Test - public void addFieldToVariableSetTest1() throws CatalogDBException, CatalogAuthorizationException { + public void addFieldToVariableSetTest1() throws CatalogDBException, CatalogAuthorizationException, CatalogParameterException { createExampleVariableSet("VARSET_1", false); createExampleVariableSet("VARSET_2", true); Variable variable = new Variable("NAM", "", Variable.VariableType.STRING, "", true, false, Collections.emptyList(), null, 0, "", "", null, Collections.emptyMap()); - DataResult result = catalogStudyDBAdaptor.addFieldToVariableSet(18, variable, user3.getId()); + DataResult result = catalogStudyDBAdaptor.addFieldToVariableSet(5L, 18, variable, user3.getId()); assertEquals(1, result.getNumUpdated()); DataResult queryResult = catalogStudyDBAdaptor.getVariableSet(18L, QueryOptions.empty()); @@ -170,7 +170,7 @@ public void addFieldToVariableSetTest1() throws CatalogDBException, CatalogAutho // We try to insert the same one again. thrown.expect(CatalogDBException.class); thrown.expectMessage("already exist"); - catalogStudyDBAdaptor.addFieldToVariableSet(18, variable, user3.getId()); + catalogStudyDBAdaptor.addFieldToVariableSet(5L, 18, variable, user3.getId()); } /** @@ -179,12 +179,12 @@ public void addFieldToVariableSetTest1() throws CatalogDBException, CatalogAutho * @throws CatalogDBException */ @Test - public void addFieldToVariableSetTest2() throws CatalogDBException, CatalogAuthorizationException { + public void addFieldToVariableSetTest2() throws CatalogDBException, CatalogAuthorizationException, CatalogParameterException { Variable variable = new Variable("NAM", "", Variable.VariableType.STRING, "", true, false, Collections.emptyList(), null, 0, "", "", null, Collections.emptyMap()); thrown.expect(CatalogDBException.class); thrown.expectMessage("not found"); - catalogStudyDBAdaptor.addFieldToVariableSet(18, variable, user3.getId()); + catalogStudyDBAdaptor.addFieldToVariableSet(5L, 18, variable, user3.getId()); } @Test From d095e97ea358819b77f13a2c8142bbd0a6486e09 Mon Sep 17 00:00:00 2001 From: pfurio Date: Thu, 7 Mar 2024 11:29:33 +0100 Subject: [PATCH 04/85] catalog: implement file move in MongoDBAdaptor, #TASK-5716 --- .../executors/CatalogCommandExecutor.java | 2 +- .../opencga/catalog/db/api/FileDBAdaptor.java | 26 -- .../db/mongodb/FileMongoDBAdaptor.java | 289 +++++++++++------- .../db/mongodb/MongoDBAdaptorFactory.java | 7 +- .../catalog/managers/CatalogManager.java | 4 +- .../opencga/catalog/managers/FileManager.java | 142 +++------ .../opencga/catalog/managers/FileUtils.java | 134 +++++++- .../catalog/utils/FileMetadataReader.java | 23 +- .../db/mongodb/AuditMongoDBAdaptorTest.java | 3 +- .../db/mongodb/FileMongoDBAdaptorTest.java | 24 -- .../db/mongodb/MongoDBAdaptorTest.java | 3 +- .../CatalogManagerExternalResource.java | 3 +- .../catalog/managers/FileManagerTest.java | 217 +++++++------ .../migration/MigrationManagerTest.java | 3 +- .../opencga/core/models/common/Enums.java | 1 + .../core/models/file/FileMoveParams.java | 18 ++ .../core/models/file/FileUpdateParams.java | 45 +-- .../core/tools/result/ExecutionResult.java | 2 - .../core/config/ConfigurationTest.java | 69 ++++- .../monitor/daemons/MonitorParentDaemon.java | 2 +- .../opencga/server/rest/FileWSServer.java | 21 ++ 21 files changed, 620 insertions(+), 418 deletions(-) create mode 100644 opencga-core/src/main/java/org/opencb/opencga/core/models/file/FileMoveParams.java diff --git a/opencga-app/src/main/java/org/opencb/opencga/app/cli/admin/executors/CatalogCommandExecutor.java b/opencga-app/src/main/java/org/opencb/opencga/app/cli/admin/executors/CatalogCommandExecutor.java index 12564ec4880..40ece671445 100644 --- a/opencga-app/src/main/java/org/opencb/opencga/app/cli/admin/executors/CatalogCommandExecutor.java +++ b/opencga-app/src/main/java/org/opencb/opencga/app/cli/admin/executors/CatalogCommandExecutor.java @@ -136,7 +136,7 @@ private void status() throws CatalogException, JsonProcessingException { if (catalogManager.existsCatalogDB()) { result.put("installed", true); - MongoDBAdaptorFactory factory = new MongoDBAdaptorFactory(configuration); + MongoDBAdaptorFactory factory = new MongoDBAdaptorFactory(configuration, catalogManager.getIoManagerFactory()); MongoDBCollection metaCollection = factory.getMongoDBCollectionMap().get(MongoDBAdaptorFactory.METADATA_COLLECTION); Document metaDocument = metaCollection.find(new Document(), QueryOptions.empty()).first(); diff --git a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/api/FileDBAdaptor.java b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/api/FileDBAdaptor.java index 1ed15060d91..86e62f1ebc1 100644 --- a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/api/FileDBAdaptor.java +++ b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/api/FileDBAdaptor.java @@ -287,32 +287,6 @@ OpenCGAResult get(long fileId, QueryOptions options) OpenCGAResult getAllInStudy(long studyId, QueryOptions options) throws CatalogDBException, CatalogParameterException, CatalogAuthorizationException; - /*** - * Retrieves all the files present in the folder. - * - * @param studyId Study id where the files will be extracted from. - * @param path Directory where the files will be extracted from. - * @param options Options to filter the file output. - * @return A OpenCGAResult object containing the files present in the folder of the given study. - * @throws CatalogDBException when the study or the path does not exist. - */ - OpenCGAResult getAllFilesInFolder(long studyId, String path, QueryOptions options) throws CatalogDBException; - - /*** - * Renames the file. - * - * @param fileId Id of the file to be renamed. - * @param filePath New file or directory name (containing the full path). - * @param fileUri New file uri (containing the full path). - * @param options Options to filter the file output. - * @return A OpenCGAResult object. - * @throws CatalogDBException when the filePath already exists. - * @throws CatalogParameterException if there is any formatting error. - * @throws CatalogAuthorizationException if the user is not authorised to perform the query. - */ - OpenCGAResult rename(long fileId, String filePath, String fileUri, QueryOptions options) - throws CatalogDBException, CatalogParameterException, CatalogAuthorizationException; - /** * Removes the mark of the permission rule (if existed) from all the entries from the study to notify that permission rule would need to * be applied. diff --git a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/FileMongoDBAdaptor.java b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/FileMongoDBAdaptor.java index d283a09fd2b..a0811254e65 100644 --- a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/FileMongoDBAdaptor.java +++ b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/FileMongoDBAdaptor.java @@ -19,6 +19,8 @@ import com.mongodb.client.ClientSession; import com.mongodb.client.model.Filters; import com.mongodb.client.model.Updates; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.collections4.MapUtils; import org.apache.commons.lang3.NotImplementedException; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.time.StopWatch; @@ -32,16 +34,17 @@ import org.opencb.opencga.catalog.db.api.SampleDBAdaptor; import org.opencb.opencga.catalog.db.mongodb.converters.FileConverter; import org.opencb.opencga.catalog.db.mongodb.iterators.FileCatalogMongoDBIterator; -import org.opencb.opencga.catalog.exceptions.CatalogAuthorizationException; -import org.opencb.opencga.catalog.exceptions.CatalogDBException; -import org.opencb.opencga.catalog.exceptions.CatalogException; -import org.opencb.opencga.catalog.exceptions.CatalogParameterException; +import org.opencb.opencga.catalog.exceptions.*; +import org.opencb.opencga.catalog.io.IOManagerFactory; +import org.opencb.opencga.catalog.managers.FileManager; +import org.opencb.opencga.catalog.managers.FileUtils; import org.opencb.opencga.catalog.managers.SampleManager; import org.opencb.opencga.catalog.utils.Constants; import org.opencb.opencga.catalog.utils.ParamUtils.BasicUpdateAction; import org.opencb.opencga.catalog.utils.UuidUtils; import org.opencb.opencga.core.api.ParamConstants; import org.opencb.opencga.core.common.TimeUtils; +import org.opencb.opencga.core.common.UriUtils; import org.opencb.opencga.core.config.Configuration; import org.opencb.opencga.core.models.common.AnnotationSet; import org.opencb.opencga.core.models.common.Enums; @@ -54,9 +57,9 @@ import org.slf4j.LoggerFactory; import javax.annotation.Nullable; +import java.io.IOException; import java.net.URI; -import java.nio.file.Path; -import java.nio.file.Paths; +import java.net.URISyntaxException; import java.util.*; import java.util.concurrent.TimeUnit; import java.util.function.Consumer; @@ -81,21 +84,33 @@ public class FileMongoDBAdaptor extends AnnotationMongoDBAdaptor implement private FileConverter fileConverter; private int fileSampleLinkThreshold = 5000; + private final IOManagerFactory ioManagerFactory; + + private enum UpdateAttributeParams { + NESTED_PATH_UPDATE, + PREVIOUS_FILE_ID, + NEW_FILE_ID, + SET_SAMPLES, + ADDED_SAMPLES, + REMOVED_SAMPLES + } + /*** * CatalogMongoFileDBAdaptor constructor. - * - * @param fileCollection MongoDB connection to the file collection. + * @param fileCollection MongoDB connection to the file collection. * @param deletedFileCollection MongoDB connection to the file collection containing the deleted documents. * @param configuration Configuration file. * @param dbAdaptorFactory Generic dbAdaptorFactory containing all the different collections. + * @param ioManagerFactory IOManagerFactory. */ public FileMongoDBAdaptor(MongoDBCollection fileCollection, MongoDBCollection deletedFileCollection, Configuration configuration, - MongoDBAdaptorFactory dbAdaptorFactory) { + MongoDBAdaptorFactory dbAdaptorFactory, IOManagerFactory ioManagerFactory) { super(configuration, LoggerFactory.getLogger(FileMongoDBAdaptor.class)); this.dbAdaptorFactory = dbAdaptorFactory; this.fileCollection = fileCollection; this.deletedFileCollection = deletedFileCollection; this.fileConverter = new FileConverter(); + this.ioManagerFactory = ioManagerFactory; } @Override @@ -272,14 +287,6 @@ public OpenCGAResult getAllInStudy(long studyId, QueryOptions options) return get(query, options); } - @Override - public OpenCGAResult getAllFilesInFolder(long studyId, String path, QueryOptions options) throws CatalogDBException { - long startTime = startQuery(); - Bson query = Filters.and(Filters.eq(PRIVATE_STUDY_UID, studyId), Filters.regex("path", "^" + path + "[^/]+/?$")); - DataResult fileResults = fileCollection.find(query, fileConverter, null); - return endQuery(startTime, fileResults); - } - @Override public long getStudyIdByFileId(long fileId) throws CatalogDBException, CatalogParameterException, CatalogAuthorizationException { Query query = new Query(QueryParams.UID.key(), fileId); @@ -325,7 +332,8 @@ public OpenCGAResult update(long id, ObjectMap parameters, QueryOptions queryOpt public OpenCGAResult update(long fileUid, ObjectMap parameters, List variableSetList, QueryOptions queryOptions) throws CatalogDBException, CatalogParameterException, CatalogAuthorizationException { QueryOptions options = new QueryOptions(QueryOptions.INCLUDE, - Arrays.asList(QueryParams.ID.key(), QueryParams.UID.key(), QueryParams.SIZE.key(), QueryParams.STUDY_UID.key())); + Arrays.asList(QueryParams.ID.key(), QueryParams.UID.key(), QueryParams.PATH.key(), QueryParams.SIZE.key(), + QueryParams.STUDY_UID.key())); OpenCGAResult fileDataResult = get(fileUid, options); if (fileDataResult.getNumResults() == 0) { @@ -354,7 +362,7 @@ public OpenCGAResult update(Query query, ObjectMap parameters, List Arrays.asList(QueryParams.ID.key(), QueryParams.UID.key(), QueryParams.SIZE.key(), QueryParams.STUDY_UID.key())); DBIterator iterator = iterator(query, options); - OpenCGAResult result = OpenCGAResult.empty(); + OpenCGAResult result = OpenCGAResult.empty(File.class); while (iterator.hasNext()) { File file = iterator.next(); @@ -381,6 +389,10 @@ OpenCGAResult transactionalUpdate(ClientSession clientSession, File file, Query tmpQuery = new Query() .append(QueryParams.STUDY_UID.key(), studyUid) .append(QueryParams.UID.key(), fileUid); + QueryOptions options = new QueryOptions(QueryOptions.INCLUDE, + Arrays.asList(QueryParams.ID.key(), QueryParams.UID.key(), QueryParams.PATH.key(), QueryParams.URI.key(), + QueryParams.TYPE.key(), QueryParams.SIZE.key(), QueryParams.STUDY_UID.key())); + File completeFile = get(clientSession, tmpQuery, options).first(); // We perform the update. Bson queryBson = parseQuery(tmpQuery); @@ -406,19 +418,20 @@ OpenCGAResult transactionalUpdate(ClientSession clientSession, File file, // If the size of some of the files have been changed, notify to the correspondent study if (parameters.containsKey(QueryParams.SIZE.key())) { long newDiskUsage = parameters.getLong(QueryParams.SIZE.key()); - long difDiskUsage = newDiskUsage - file.getSize(); + long difDiskUsage = newDiskUsage - completeFile.getSize(); dbAdaptorFactory.getCatalogStudyDBAdaptor().updateDiskUsage(clientSession, studyUid, difDiskUsage); } - updateSampleReferences(clientSession, file, updateDocument); + updateSampleReferences(clientSession, completeFile, updateDocument); + updateWhenFileIdChanged(clientSession, completeFile, updateDocument, queryOptions); if (result.getNumMatches() == 0) { - throw new CatalogDBException("File " + file.getPath() + " not found"); + throw new CatalogDBException("File " + completeFile.getPath() + " not found"); } if (result.getNumUpdated() == 0) { - events.add(new Event(Event.Type.WARNING, file.getPath(), "File was already updated")); + events.add(new Event(Event.Type.WARNING, completeFile.getPath(), "File was already updated")); } - logger.debug("File {} successfully updated", file.getPath()); + logger.debug("File {} successfully updated", completeFile.getPath()); } return endWrite(tmpStartTime, 1, 1, events); @@ -436,7 +449,7 @@ OpenCGAResult transactionalUpdate(ClientSession clientSession, long studyU } List events = new ArrayList<>(); - logger.debug("Update file. Query: {}, Update: {}", query.toBsonDocument(), fileUpdate.toBsonDocument()); + logger.debug("Update file. Query: {}, Update: {}", query.toBsonDocument(), fileUpdate.toBsonDocument()); DataResult result = fileCollection.update(clientSession, query, fileUpdate, null); logger.debug("{} file(s) successfully updated", result.getNumUpdated()); @@ -447,13 +460,12 @@ OpenCGAResult transactionalUpdate(ClientSession clientSession, long studyU private void updateSampleReferences(ClientSession clientSession, File file, UpdateDocument updateDocument) throws CatalogDBException, CatalogParameterException, CatalogAuthorizationException { if (!updateDocument.getAttributes().isEmpty()) { - ObjectMap addedSamples = (ObjectMap) updateDocument.getAttributes().getMap("ADDED_SAMPLES"); - ObjectMap removedSamples = (ObjectMap) updateDocument.getAttributes().getMap("REMOVED_SAMPLES"); - List setSamples = updateDocument.getAttributes().getAsLongList("SET_SAMPLES"); + ObjectMap addedSamples = (ObjectMap) updateDocument.getAttributes().getMap(UpdateAttributeParams.ADDED_SAMPLES.name()); + ObjectMap removedSamples = (ObjectMap) updateDocument.getAttributes().getMap(UpdateAttributeParams.REMOVED_SAMPLES.name()); + List setSamples = updateDocument.getAttributes().getAsLongList(UpdateAttributeParams.SET_SAMPLES.name()); - if (setSamples.isEmpty() && (addedSamples == null || addedSamples.isEmpty()) - && (removedSamples == null || removedSamples.isEmpty())) { - throw new CatalogDBException("Internal error: Expected a list of added, removed or set samples"); + if (CollectionUtils.isEmpty(setSamples) && MapUtils.isEmpty(addedSamples) && MapUtils.isEmpty(removedSamples)) { + return; } Bson sampleBsonQuery; @@ -511,6 +523,61 @@ private void updateSampleReferences(ClientSession clientSession, File file, Upda } } + private void updateWhenFileIdChanged(ClientSession clientSession, File file, UpdateDocument updateDocument, QueryOptions options) + throws CatalogDBException, CatalogParameterException, CatalogAuthorizationException { + String newFileId = updateDocument.getSet().getString(QueryParams.ID.key()); + if (StringUtils.isEmpty(newFileId)) { + return; + } + + Query query = new Query() + .append(SampleDBAdaptor.QueryParams.STUDY_UID.key(), file.getStudyUid()) + .append(SampleDBAdaptor.QueryParams.FILE_IDS.key(), file.getId()); + Bson sampleBsonQuery = dbAdaptorFactory.getCatalogSampleDBAdaptor().parseQuery(query, null); + + // Replace the id for the new one + UpdateDocument sampleUpdate = new UpdateDocument(); + sampleUpdate.getSet().append(SampleDBAdaptor.QueryParams.FILE_IDS.key() + ".$", newFileId); + + dbAdaptorFactory.getCatalogSampleDBAdaptor().transactionalUpdate(clientSession, file.getStudyUid(), sampleBsonQuery, sampleUpdate); + + String skipMoveFileString = "_SKIP_MOVE_FILE"; + if (file.getType().equals(File.Type.DIRECTORY)) { + // We get the files and folders directly under this directory + Query tmpQuery = new Query() + .append(QueryParams.STUDY_UID.key(), file.getStudyUid()) + .append(QueryParams.DIRECTORY.key(), file.getPath()); + String newPath = updateDocument.getSet().getString(QueryParams.PATH.key()); + try (DBIterator iterator = iterator(clientSession, tmpQuery, FileManager.INCLUDE_FILE_URI_PATH)) { + while (iterator.hasNext()) { + File tmpFile = iterator.next(); + String targetPath = newPath + tmpFile.getName(); + if (File.Type.DIRECTORY.equals(tmpFile.getType())) { + targetPath = targetPath + "/"; + } + ObjectMap updateMap = new ObjectMap(QueryParams.PATH.key(), targetPath); + QueryOptions queryOptions = new QueryOptions(skipMoveFileString, true); + OpenCGAResult result = transactionalUpdate(clientSession, tmpFile, updateMap, null, queryOptions); + if (result.getNumUpdated() == 0) { + throw new CatalogDBException("Could not update path from '" + tmpFile.getPath() + "' to '" + targetPath + "'"); + } + } + } + } + + String newUri = updateDocument.getSet().getString(QueryParams.URI.key()); + if (file.getUri() != null && StringUtils.isNotEmpty(newUri) && !newUri.equals(file.getUri().toString()) + && !options.getBoolean(skipMoveFileString)) { + // Move just the main folder/file + logger.info("Move file from uri '{}' to '{}'", file.getUri(), newUri); + try { + ioManagerFactory.get(file.getUri()).move(file.getUri(), UriUtils.createUri(newUri)); + } catch (CatalogIOException | IOException | URISyntaxException e) { + throw new CatalogDBException("Could not move file/folder physically", e); + } + } + } + private void getSampleChanges(Document fileDocument, List sampleList, UpdateDocument updateDocument, BasicUpdateAction operation) { String fileId = fileDocument.getString(QueryParams.ID.key()); @@ -525,7 +592,7 @@ private void getSampleChanges(Document fileDocument, List sampleList, Up // The file id has been altered !!! if (updateDocument.getSet().containsKey(QueryParams.ID.key())) { // The current list of samples need to replace the current fileId - updateDocument.getAttributes().put("SET_SAMPLES", currentSampleUidList); + updateDocument.getAttributes().put(UpdateAttributeParams.SET_SAMPLES.name(), currentSampleUidList); } else if (BasicUpdateAction.SET.equals(operation) || BasicUpdateAction.ADD.equals(operation)) { // We will see which of the samples are actually new List samplesToAdd = new ArrayList<>(); @@ -537,7 +604,7 @@ private void getSampleChanges(Document fileDocument, List sampleList, Up } if (!samplesToAdd.isEmpty()) { - updateDocument.getAttributes().put("ADDED_SAMPLES", new ObjectMap(fileId, samplesToAdd)); + updateDocument.getAttributes().put(UpdateAttributeParams.ADDED_SAMPLES.name(), new ObjectMap(fileId, samplesToAdd)); } if (BasicUpdateAction.SET.equals(operation) && fileDocument.get(PRIVATE_SAMPLES) != null) { @@ -553,7 +620,8 @@ private void getSampleChanges(Document fileDocument, List sampleList, Up } if (!samplesToRemove.isEmpty()) { - updateDocument.getAttributes().put("REMOVED_SAMPLES", new ObjectMap(fileId, samplesToRemove)); + updateDocument.getAttributes().put(UpdateAttributeParams.REMOVED_SAMPLES.name(), + new ObjectMap(fileId, samplesToRemove)); } } } else if (BasicUpdateAction.REMOVE.equals(operation)) { @@ -567,7 +635,7 @@ private void getSampleChanges(Document fileDocument, List sampleList, Up } if (!samplesToRemove.isEmpty()) { - updateDocument.getAttributes().put("REMOVED_SAMPLES", new ObjectMap(fileId, samplesToRemove)); + updateDocument.getAttributes().put(UpdateAttributeParams.REMOVED_SAMPLES.name(), new ObjectMap(fileId, samplesToRemove)); } } } @@ -578,10 +646,8 @@ private UpdateDocument getValidatedUpdateParams(ClientSession clientSession, lon UpdateDocument document = new UpdateDocument(); String[] acceptedParams = { - QueryParams.DESCRIPTION.key(), QueryParams.URI.key(), QueryParams.PATH.key(), QueryParams.CHECKSUM.key(), - QueryParams.JOB_ID.key(), + QueryParams.DESCRIPTION.key(), QueryParams.URI.key(), QueryParams.CHECKSUM.key(), QueryParams.JOB_ID.key(), }; - // Fixme: Add "name", "path" and "ownerId" at some point. At the moment, it would lead to inconsistencies. filterStringParams(parameters, document.getSet(), acceptedParams); if (StringUtils.isNotEmpty(parameters.getString(QueryParams.CREATION_DATE.key()))) { @@ -598,17 +664,79 @@ private UpdateDocument getValidatedUpdateParams(ClientSession clientSession, lon } if (parameters.containsKey(QueryParams.PATH.key())) { - checkOnlyOneFileMatches(clientSession, query); + OpenCGAResult results = get(clientSession, query, FileManager.INCLUDE_FILE_URI_PATH); + if (results.getNumResults() > 1) { + throw new CatalogDBException("Cannot set same path to multiple files."); + } + File currentFile = results.first(); + + // Check desired path is not in use by other file + String desiredPath = parameters.getString(QueryParams.PATH.key()); + desiredPath = FileUtils.fixPath(desiredPath, currentFile.getType()); + document.getSet().put(QueryParams.PATH.key(), desiredPath); + + if (desiredPath.equals(currentFile.getPath())) { + throw new CatalogDBException("Nothing to do. The path of the file was already '" + desiredPath + "'."); + } + if (StringUtils.isEmpty(desiredPath)) { + throw new CatalogDBException("Cannot rename root folder."); + } + Query tmpQuery = new Query() + .append(QueryParams.STUDY_UID.key(), studyUid) + .append(QueryParams.PATH.key(), desiredPath); + OpenCGAResult countResult = count(clientSession, tmpQuery); + if (countResult.getNumMatches() > 0) { + throw new CatalogDBException("There already exists another file under path '" + desiredPath + "'."); + } - // Check the path is not in use - Query pathQuery = new Query(QueryParams.PATH.key(), parameters.getString(QueryParams.PATH.key())); - if (count(clientSession, pathQuery).getNumMatches() > 0) { - throw new CatalogDBException("Path " + parameters.getString(QueryParams.PATH.key()) + " already in use"); + // Look for parent folder to check a few things more + List pathList = FileUtils.calculateAllPossiblePaths(desiredPath); + tmpQuery = new Query() + .append(QueryParams.STUDY_UID.key(), studyUid) + .append(QueryParams.PATH.key(), pathList); + OpenCGAResult parentFiles = get(clientSession, tmpQuery, FileManager.INCLUDE_FILE_URI_PATH); + if (parentFiles.getNumResults() + 1 < pathList.size()) { + Set presentFolders = parentFiles.getResults().stream().map(File::getPath).collect(Collectors.toSet()); + String missingFolders = pathList.stream().filter(p -> !presentFolders.contains(p)).collect(Collectors.joining(", ")); + throw new CatalogDBException("Can't move file to path '" + desiredPath + "'. Please, create missing parent folders: " + + missingFolders); + } + + File desiredParentFolder = parentFiles.first(); + for (File tmpParentFile : parentFiles.getResults()) { + // Look for the closest parentFolder + if (tmpParentFile.getPath().length() > desiredParentFolder.getPath().length()) { + desiredParentFolder = tmpParentFile; + } } - // We also update the ID replacing the / for : - String path = parameters.getString(QueryParams.PATH.key()); - document.getSet().put(QueryParams.ID.key(), StringUtils.replace(path, "/", ":")); + boolean changeUri = true; + if (desiredParentFolder.isExternal() && !currentFile.isExternal()) { + throw new CatalogDBException("Cannot move file to path '" + desiredPath + "'. The folder '" + desiredParentFolder.getPath() + + "' is linked to the external physical uri '" + desiredParentFolder.getUri() + "' so OpenCGA can't move" + + " anything there."); + } else if (desiredParentFolder.isExternal() && currentFile.isExternal()) { + changeUri = false; + } + + if (changeUri) { + URI fileUri = null; + try { + fileUri = FileUtils.getFileUri(desiredPath, desiredParentFolder, currentFile.getType()); + } catch (URISyntaxException e) { + throw new CatalogDBException("Could not update file.", e); + } + document.getSet().put(QueryParams.URI.key(), fileUri.toString()); + } + + String name = FileUtils.getFileName(desiredPath); + String newFileId = FileUtils.getFileId(desiredPath); + document.getSet().put(QueryParams.ID.key(), newFileId); + document.getSet().put(QueryParams.NAME.key(), name); + document.getSet().put(REVERSE_NAME, StringUtils.reverse(name)); + + document.getAttributes().put(UpdateAttributeParams.PREVIOUS_FILE_ID.name(), currentFile.getId()); + document.getAttributes().put(UpdateAttributeParams.NEW_FILE_ID.name(), newFileId); } // Check if the tags exist. @@ -758,20 +886,6 @@ private UpdateDocument getValidatedUpdateParams(ClientSession clientSession, lon return document; } - private File checkOnlyOneFileMatches(ClientSession clientSession, Query query) - throws CatalogDBException, CatalogParameterException, CatalogAuthorizationException { - Query tmpQuery = new Query(query); - - OpenCGAResult fileResult = get(clientSession, tmpQuery, new QueryOptions()); - if (fileResult.getNumResults() == 0) { - throw new CatalogDBException("Update file: No file found to be updated"); - } - if (fileResult.getNumResults() > 1) { - throw CatalogDBException.cannotUpdateMultipleEntries(QueryParams.ID.key(), "file"); - } - return fileResult.first(); - } - @Override public OpenCGAResult delete(File file) throws CatalogDBException { throw new UnsupportedOperationException("Use delete passing status field."); @@ -970,55 +1084,6 @@ OpenCGAResult privateDelete(ClientSession clientSession, Document fileDo // return endWrite(tmpStartTime, 1, 0, 0, 1, events); // } - @Override - public OpenCGAResult rename(long fileUid, String filePath, String fileUri, QueryOptions options) - throws CatalogDBException, CatalogParameterException, CatalogAuthorizationException { - checkId(fileUid); - - Path path = Paths.get(filePath); - String fileName = path.getFileName().toString(); - - Document fileDoc = nativeGet(new Query(QueryParams.UID.key(), fileUid), null).getResults().get(0); - File file = fileConverter.convertToDataModelType(fileDoc, options); - - if (file.getType().equals(File.Type.DIRECTORY)) { - filePath += filePath.endsWith("/") ? "" : "/"; - } - - long studyId = (long) fileDoc.get(PRIVATE_STUDY_UID); - long collisionFileId = getId(studyId, filePath); - if (collisionFileId >= 0) { - throw new CatalogDBException("Can not rename: " + filePath + " already exists"); - } - - if (file.getType().equals(File.Type.DIRECTORY)) { // recursive over the files inside folder - OpenCGAResult allFilesInFolder = getAllFilesInFolder(studyId, file.getPath(), null); - String oldPath = file.getPath(); - URI uri = file.getUri(); - String oldUri = uri != null ? uri.toString() : ""; - for (File subFile : allFilesInFolder.getResults()) { - String replacedPath = subFile.getPath().replaceFirst(oldPath, filePath); - String replacedUri = subFile.getUri().toString().replaceFirst(oldUri, fileUri); - rename(subFile.getUid(), replacedPath, replacedUri, null); // first part of the path in the subfiles 3 - } - } - - String fileId = StringUtils.replace(filePath, "/", ":"); - - Document query = new Document(PRIVATE_UID, fileUid); - Document set = new Document("$set", new Document() - .append(QueryParams.ID.key(), fileId) - .append(QueryParams.NAME.key(), fileName) - .append(REVERSE_NAME, StringUtils.reverse(fileName)) - .append(QueryParams.PATH.key(), filePath) - .append(QueryParams.URI.key(), fileUri)); - DataResult result = fileCollection.update(query, set, null); - if (result.getNumUpdated() == 0) { - throw CatalogDBException.uidNotFound("File", fileUid); - } - return new OpenCGAResult(result); - } - @Override public OpenCGAResult restore(Query query, QueryOptions queryOptions) throws CatalogDBException { throw new NotImplementedException("Not yet implemented"); @@ -1092,7 +1157,7 @@ public OpenCGAResult nativeGet(Query query, QueryOptions options) return nativeGet(null, query, options); } - public OpenCGAResult nativeGet(ClientSession clientSession, Query query, QueryOptions options) + public OpenCGAResult nativeGet(ClientSession clientSession, Query query, QueryOptions options) throws CatalogDBException, CatalogParameterException, CatalogAuthorizationException { long startTime = startQuery(); try (DBIterator dbIterator = nativeIterator(clientSession, query, options)) { @@ -1101,12 +1166,12 @@ public OpenCGAResult nativeGet(ClientSession clientSession, Query query, QueryOp } @Override - public OpenCGAResult nativeGet(long studyUid, Query query, QueryOptions options, String user) + public OpenCGAResult nativeGet(long studyUid, Query query, QueryOptions options, String user) throws CatalogDBException, CatalogAuthorizationException, CatalogParameterException { return nativeGet(null, studyUid, query, options, user); } - public OpenCGAResult nativeGet(ClientSession clientSession, long studyUid, Query query, QueryOptions options, String user) + public OpenCGAResult nativeGet(ClientSession clientSession, long studyUid, Query query, QueryOptions options, String user) throws CatalogDBException, CatalogAuthorizationException, CatalogParameterException { long startTime = startQuery(); try (DBIterator dbIterator = nativeIterator(clientSession, studyUid, query, options, user)) { diff --git a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/MongoDBAdaptorFactory.java b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/MongoDBAdaptorFactory.java index 05acf9aed2b..8dff0ee6129 100644 --- a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/MongoDBAdaptorFactory.java +++ b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/MongoDBAdaptorFactory.java @@ -31,6 +31,7 @@ import org.opencb.opencga.catalog.db.api.MigrationDBAdaptor; import org.opencb.opencga.catalog.exceptions.CatalogDBException; import org.opencb.opencga.catalog.exceptions.CatalogException; +import org.opencb.opencga.catalog.io.IOManagerFactory; import org.opencb.opencga.core.config.Admin; import org.opencb.opencga.core.config.Configuration; import org.slf4j.Logger; @@ -140,6 +141,7 @@ public class MongoDBAdaptorFactory implements DBAdaptorFactory { ); static final String METADATA_OBJECT_ID = "METADATA"; + private final IOManagerFactory ioManagerFactory; private final MongoDataStoreManager mongoManager; private final MongoDBConfiguration configuration; private final String database; @@ -165,7 +167,7 @@ public class MongoDBAdaptorFactory implements DBAdaptorFactory { private Logger logger; - public MongoDBAdaptorFactory(Configuration catalogConfiguration) throws CatalogDBException { + public MongoDBAdaptorFactory(Configuration catalogConfiguration, IOManagerFactory ioManagerFactory) throws CatalogDBException { List dataStoreServerAddresses = new LinkedList<>(); for (String host : catalogConfiguration.getCatalog().getDatabase().getHosts()) { if (host.contains(":")) { @@ -188,6 +190,7 @@ public MongoDBAdaptorFactory(Configuration catalogConfiguration) throws CatalogD this.mongoManager = new MongoDataStoreManager(dataStoreServerAddresses); this.configuration = mongoDBConfiguration; this.database = getCatalogDatabase(catalogConfiguration.getDatabasePrefix()); + this.ioManagerFactory = ioManagerFactory; logger = LoggerFactory.getLogger(this.getClass()); connect(catalogConfiguration); @@ -422,7 +425,7 @@ private void connect(Configuration catalogConfiguration) throws CatalogDBExcepti collections.put(AUDIT_COLLECTION, auditCollection); - fileDBAdaptor = new FileMongoDBAdaptor(fileCollection, deletedFileCollection, catalogConfiguration, this); + fileDBAdaptor = new FileMongoDBAdaptor(fileCollection, deletedFileCollection, catalogConfiguration, this, ioManagerFactory); familyDBAdaptor = new FamilyMongoDBAdaptor(familyCollection, familyArchivedCollection, deletedFamilyCollection, catalogConfiguration, this); individualDBAdaptor = new IndividualMongoDBAdaptor(individualCollection, individualArchivedCollection, deletedIndividualCollection, diff --git a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/managers/CatalogManager.java b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/managers/CatalogManager.java index 8811832480d..855c396b74f 100644 --- a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/managers/CatalogManager.java +++ b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/managers/CatalogManager.java @@ -83,10 +83,10 @@ public class CatalogManager implements AutoCloseable { public CatalogManager(Configuration configuration) throws CatalogException { this.configuration = configuration; - logger.debug("CatalogManager configureDBAdaptorFactory"); - catalogDBAdaptorFactory = new MongoDBAdaptorFactory(configuration); logger.debug("CatalogManager configureIOManager"); configureIOManager(configuration); + logger.debug("CatalogManager configureDBAdaptorFactory"); + catalogDBAdaptorFactory = new MongoDBAdaptorFactory(configuration, ioManagerFactory); logger.debug("CatalogManager configureManager"); configureManagers(configuration); } diff --git a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/managers/FileManager.java b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/managers/FileManager.java index 3d643c17bb2..0832d689440 100644 --- a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/managers/FileManager.java +++ b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/managers/FileManager.java @@ -2226,13 +2226,6 @@ private OpenCGAResult update(Study study, File file, FileUpdateParams upda userId, false); } - //Name must be changed with "rename". - if (updateParams != null && StringUtils.isNotEmpty(updateParams.getName())) { - logger.info("Rename file using update method!"); - rename(study.getFqn(), file.getPath(), updateParams.getName(), token); - parameters.remove(FileDBAdaptor.QueryParams.NAME.key()); - } - checkUpdateAnnotations(study, file, parameters, options, VariableSet.AnnotableDataModels.FILE, fileDBAdaptor, userId); OpenCGAResult update = fileDBAdaptor.update(file.getUid(), parameters, study.getVariableSets(), options); @@ -2288,12 +2281,6 @@ public OpenCGAResult update(String studyStr, String entryStr, ObjectMap pa catalogManager.getSampleManager().internalGet(study.getUid(), sampleIds, SampleManager.INCLUDE_SAMPLE_IDS, userId, false); } - //Name must be changed with "rename". - if (parameters.containsKey(FileDBAdaptor.QueryParams.NAME.key())) { - logger.info("Rename file using update method!"); - rename(studyStr, file.getPath(), parameters.getString(FileDBAdaptor.QueryParams.NAME.key()), token); - } - OpenCGAResult queryResult = unsafeUpdate(study, file, parameters, options, userId); auditManager.auditUpdate(userId, Enums.Resource.FILE, file.getId(), file.getUuid(), study.getId(), study.getUuid(), auditParams, new AuditRecord.Status(AuditRecord.Status.Result.SUCCESS)); @@ -2323,6 +2310,52 @@ OpenCGAResult unsafeUpdate(Study study, File file, ObjectMap parameters, Q return fileDBAdaptor.get(file.getUid(), options); } + public OpenCGAResult move(String studyStr, String entryStr, String targetPathStr, QueryOptions options, String token) + throws CatalogException { + String userId = userManager.getUserId(token); + Study study = studyManager.resolveId(studyStr, userId); + + ObjectMap auditParams = new ObjectMap() + .append("study", studyStr) + .append("file", entryStr) + .append("target", targetPathStr) + .append("options", options) + .append("token", token); + + String fileId = entryStr; + String fileUuid = ""; + try { + File file = internalGet(study.getUid(), entryStr, QueryOptions.empty(), userId).first(); + fileId = file.getId(); + fileUuid = file.getUuid(); + // Check user has write permissions on file/folder + authorizationManager.checkFilePermission(study.getUid(), file.getUid(), userId, FilePermissions.WRITE); + + OpenCGAResult parents = getParents(study.getUid(), targetPathStr, false, INCLUDE_FILE_IDS); + // Check user can write in target path + File parentFolder = parents.first(); + authorizationManager.checkFilePermission(study.getUid(), parentFolder.getUid(), userId, FilePermissions.WRITE); + + ObjectMap parameters = new ObjectMap(FileDBAdaptor.QueryParams.PATH.key(), targetPathStr); + OpenCGAResult update = fileDBAdaptor.update(file.getUid(), parameters, Collections.emptyList(), QueryOptions.empty()); + + auditManager.audit(userId, Enums.Action.MOVE, Enums.Resource.FILE, file.getId(), file.getUuid(), study.getId(), study.getUuid(), + auditParams, new AuditRecord.Status(AuditRecord.Status.Result.SUCCESS)); + + if (options.getBoolean(ParamConstants.INCLUDE_RESULT_PARAM)) { + // Fetch updated file + OpenCGAResult result = fileDBAdaptor.get(study.getUid(), + new Query(FileDBAdaptor.QueryParams.UID.key(), file.getUid()), options, userId); + update.setResults(result.getResults()); + } + return update; + } catch (Exception e) { + auditManager.audit(userId, Enums.Action.MOVE, Enums.Resource.FILE, fileId, fileUuid, study.getId(), study.getUuid(), + auditParams, new AuditRecord.Status(AuditRecord.Status.Result.ERROR, new Error(0, fileId, e.getMessage()))); + throw e; + } + } + public OpenCGAResult link(String studyStr, FileLinkParams params, boolean parents, String token) throws CatalogException { // We make two attempts to link to ensure the behaviour remains even if it is being called at the same time link from different // threads @@ -2416,68 +2449,6 @@ public OpenCGAResult groupBy(@Nullable String studyStr, Query query, List rename(String studyStr, String fileStr, String newName, String sessionId) throws CatalogException { - ParamUtils.checkFileName(newName, "name"); - - String userId = userManager.getUserId(sessionId); - Study study = studyManager.resolveId(studyStr, userId); - - File file = internalGet(study.getUid(), fileStr, EXCLUDE_FILE_ATTRIBUTES, userId).first(); - authorizationManager.checkFilePermission(study.getUid(), file.getUid(), userId, FilePermissions.WRITE); - - if (file.getName().equals(newName)) { - OpenCGAResult result = OpenCGAResult.empty(); - result.setEvents(Collections.singletonList(new Event(Event.Type.WARNING, newName, "File already had that name."))); - return result; - } - - if (isRootFolder(file)) { - throw new CatalogException("Can not rename root folder"); - } - - String oldPath = file.getPath(); - Path parent = Paths.get(oldPath).getParent(); - String newPath; - if (parent == null) { - newPath = newName; - } else { - newPath = parent.resolve(newName).toString(); - } - - IOManager ioManager = null; - try { - ioManager = ioManagerFactory.get(file.getUri()); - } catch (IOException e) { - throw CatalogIOException.ioManagerException(file.getUri(), e); - } - URI oldUri = file.getUri(); - URI newUri = Paths.get(oldUri).getParent().resolve(newName).toUri(); -// URI studyUri = file.getUri(); - boolean isExternal = file.isExternal(); //If the file URI is not null, the file is external located. - - switch (file.getType()) { - case DIRECTORY: - if (!isExternal) { //Only rename non external files - // TODO? check if something in the subtree is not READY? - if (ioManager.exists(oldUri)) { - ioManager.rename(oldUri, newUri); // io.move() 1 - } - } - fileDBAdaptor.rename(file.getUid(), newPath, newUri.toString(), null); - break; - case FILE: - if (!isExternal) { //Only rename non external files - ioManager.rename(oldUri, newUri); - } - fileDBAdaptor.rename(file.getUid(), newPath, newUri.toString(), null); - break; - default: - throw new CatalogException("Unknown file type " + file.getType()); - } - - return fileDBAdaptor.get(file.getUid(), QueryOptions.empty()); - } - public OpenCGAResult grep(String studyId, String fileId, String pattern, boolean ignoreCase, int numLines, String token) throws CatalogException { long startTime = System.currentTimeMillis(); @@ -2865,7 +2836,7 @@ public OpenCGAResult getParents(String studyStr, String path, boolean root String userId = userManager.getUserId(token); Study study = studyManager.resolveId(studyStr, userId); - List paths = calculateAllPossiblePaths(path); + List paths = org.opencb.opencga.catalog.managers.FileUtils.calculateAllPossiblePaths(path); Query query = new Query(FileDBAdaptor.QueryParams.PATH.key(), paths); query.put(FileDBAdaptor.QueryParams.STUDY_UID.key(), study.getUid()); @@ -2918,23 +2889,6 @@ private List getRecursiveFilesAndFolders(long studyUid, List fileLis return fileListCopy; } - private List calculateAllPossiblePaths(String filePath) { - String path = ""; - String[] split = filePath.split("/"); - List paths = new ArrayList<>(split.length + 1); - paths.add(""); //Add study root folder - //Add intermediate folders - //Do not add the last split, could be a file or a folder.. - //Depending on this, it could end with '/' or not. - for (int i = 0; i < split.length - 1; i++) { - String f = split[i]; - path = path + f + "/"; - paths.add(path); - } - paths.add(filePath); //Add the file path - return paths; - } - //FIXME: This should use org.opencb.opencga.storage.core.variant.io.VariantReaderUtils private String getMainVariantFile(String name) { if (name.endsWith(".variants.avro.gz") || name.endsWith(".variants.proto.gz") || name.endsWith(".variants.json.gz")) { @@ -2960,7 +2914,7 @@ private String getVariantMetadataFile(String path) { private OpenCGAResult getParents(long studyUid, String filePath, boolean rootFirst, QueryOptions options) throws CatalogException { - List paths = calculateAllPossiblePaths(filePath); + List paths = org.opencb.opencga.catalog.managers.FileUtils.calculateAllPossiblePaths(filePath); Query query = new Query(FileDBAdaptor.QueryParams.PATH.key(), paths); query.put(FileDBAdaptor.QueryParams.STUDY_UID.key(), studyUid); diff --git a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/managers/FileUtils.java b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/managers/FileUtils.java index 02f5cae855b..686b91cc6af 100644 --- a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/managers/FileUtils.java +++ b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/managers/FileUtils.java @@ -25,6 +25,7 @@ import org.opencb.opencga.catalog.exceptions.CatalogIOException; import org.opencb.opencga.catalog.io.IOManager; import org.opencb.opencga.catalog.utils.ParamUtils; +import org.opencb.opencga.core.common.UriUtils; import org.opencb.opencga.core.models.file.File; import org.opencb.opencga.core.models.file.FileRelatedFile; import org.opencb.opencga.core.models.file.FileStatus; @@ -36,11 +37,11 @@ import java.io.IOException; import java.io.InputStreamReader; import java.net.URI; +import java.net.URISyntaxException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; -import java.util.HashMap; -import java.util.Map; +import java.util.*; import java.util.regex.Pattern; /** @@ -463,4 +464,133 @@ public static File getVirtualFileFromPartial(File file) { return null; } + /** + * Depending on the type of the file, it will correct the path string so it always has the same format. + * + * @param path RAW path string. + * @param type FILE, DIRECTORY + * @return the path containing a trailing / if necessary, etc. + */ + public static String fixPath(String path, File.Type type) { + String finalPath = path; + if (finalPath.startsWith("/")) { + finalPath = finalPath.substring(1); + } + switch (type) { + case DIRECTORY: + if (StringUtils.isEmpty(finalPath)) { + // Root folder is represented as an empty string + return finalPath; + } + if (!finalPath.endsWith("/")) { + finalPath = finalPath + "/"; + } + return finalPath; + case FILE: + case VIRTUAL: + default: + if (finalPath.endsWith("/")) { + throw new IllegalArgumentException("File of type '" + type + "' cannot have a trailing /: '" + path + "'"); + } + return finalPath; + } + } + + /** + * Get parent path of any Catalog path using OpenCGA's format. + * Example: + * "a/b/c.txt" ----> "a/b/" + * "a/b/c/" ----> "a/b/" + * "p.txt" ----> "" + * @param strPath Path to the file or folder. + * @return the path of the parent folder. + */ + public static String getParentPath(String strPath) { + Path path = Paths.get(strPath); + Path parent = path.getParent(); + if (parent != null) { + return parent + "/"; + } else { + return ""; + } + } + + /** + * Given a path, it will return all the possible parent paths. + * Example: + * "a/b/c.txt" ---- ["", "a/", "a/b/", "a/b/c.txt"] + * "a/b/c/" ---- ["", "a/", "a/b/", "a/b/c/"] + * "p.txt" ---- ["", "p.txt"] + * "" ---- [""] + * @param filePath Path provided. + * @return A list containing all the parent paths including {@param filePath}. + */ + public static List calculateAllPossiblePaths(String filePath) { + if (StringUtils.isEmpty(filePath) || "/".equals(filePath)) { + return Collections.singletonList(""); + } + StringBuilder pathBuilder = new StringBuilder(); + String[] split = filePath.split("/"); + List paths = new ArrayList<>(split.length + 1); + paths.add(""); //Add study root folder + //Add intermediate folders + //Do not add the last split, could be a file or a folder.. + //Depending on this, it could end with '/' or not. + for (int i = 0; i < split.length - 1; i++) { + String f = split[i]; + pathBuilder = new StringBuilder(pathBuilder.toString()).append(f).append("/"); + paths.add(pathBuilder.toString()); + } + paths.add(filePath); //Add the file path + return paths; + } + + /** + * Calculate the corresponding URI for the {@param path}. + * + * @param path Path to which we need to associate the URI. + * @param parentFolder File corresponding to the folder under which the path will live. + * @param type File type. + * @return the corresponding URI for the path. + * @throws URISyntaxException if the uriStr is incorrect. + */ + public static URI getFileUri(String path, File parentFolder, File.Type type) throws URISyntaxException { + //Relative path to the existing parent + String relativePath = Paths.get(parentFolder.getPath()).relativize(Paths.get(path)).toString(); + if (path.endsWith("/") && !relativePath.endsWith("/")) { + relativePath += "/"; + } + + String uriStr = Paths.get(parentFolder.getUri().getPath()).resolve(relativePath).toString(); + + if (type.equals(File.Type.DIRECTORY)) { + return UriUtils.createDirectoryUri(uriStr); + } else { + return UriUtils.createUri(uriStr); + } + } + + /** + * Get the filename given the path {@param path}. + * @param path Path of the file. + * @return the file or directory name. + */ + public static String getFileName(String path) { + if (StringUtils.isEmpty(path)) { + return "."; + } + return Paths.get(path).getFileName().toString(); + } + + /** + * Get the file id corresponding to the file {@param path}. + * + * @param path File path. + * @return File id. + */ + public static String getFileId(String path) { + return StringUtils.replace(path, "/", ":"); + } + + } diff --git a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/utils/FileMetadataReader.java b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/utils/FileMetadataReader.java index 8a51691706f..82bebabb5aa 100644 --- a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/utils/FileMetadataReader.java +++ b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/utils/FileMetadataReader.java @@ -75,7 +75,17 @@ public void addMetadataInformation(String studyId, File file) throws CatalogExce file.setFormat(updateParams.getFormat() != null ? updateParams.getFormat() : file.getFormat()); file.setAttributes(updateParams.getAttributes() != null ? updateParams.getAttributes() : file.getAttributes()); file.setSampleIds(updateParams.getSampleIds() != null ? updateParams.getSampleIds() : file.getSampleIds()); - file.setSize(updateParams.getSize() != null ? updateParams.getSize() : file.getSize()); + + IOManager ioManager; + try { + ioManager = catalogManager.getIoManagerFactory().get(file.getUri().getScheme()); + } catch (IOException e) { + throw CatalogIOException.ioManagerException(file.getUri(), e); + } + final long fileSize = ioManager.getFileSize(file.getUri()); + if (fileSize != file.getSize()) { + file.setSize(fileSize); + } } public File updateMetadataInformation(String studyId, File file, String token) throws CatalogException { @@ -214,17 +224,6 @@ private FileUpdateParams extractMetadataInformation(String studyId, File file) t } } - IOManager ioManager; - try { - ioManager = catalogManager.getIoManagerFactory().get(file.getUri().getScheme()); - } catch (IOException e) { - throw CatalogIOException.ioManagerException(file.getUri(), e); - } - final long fileSize = ioManager.getFileSize(file.getUri()); - if (fileSize != file.getSize()) { - updateParams.setSize(fileSize); - } - return updateParams; } diff --git a/opencga-catalog/src/test/java/org/opencb/opencga/catalog/db/mongodb/AuditMongoDBAdaptorTest.java b/opencga-catalog/src/test/java/org/opencb/opencga/catalog/db/mongodb/AuditMongoDBAdaptorTest.java index 214791bed40..3a2cf146184 100644 --- a/opencga-catalog/src/test/java/org/opencb/opencga/catalog/db/mongodb/AuditMongoDBAdaptorTest.java +++ b/opencga-catalog/src/test/java/org/opencb/opencga/catalog/db/mongodb/AuditMongoDBAdaptorTest.java @@ -25,6 +25,7 @@ import org.opencb.commons.datastore.mongodb.MongoDBConfiguration; import org.opencb.commons.datastore.mongodb.MongoDataStore; import org.opencb.commons.datastore.mongodb.MongoDataStoreManager; +import org.opencb.opencga.catalog.io.IOManagerFactory; import org.opencb.opencga.core.models.audit.AuditRecord; import org.opencb.opencga.catalog.db.api.AuditDBAdaptor; import org.opencb.opencga.catalog.utils.UuidUtils; @@ -77,7 +78,7 @@ public void beforeClass() throws Exception { MongoDataStore db = mongoManager.get(database); db.getDb().drop(); - auditDbAdaptor = new MongoDBAdaptorFactory(configuration).getCatalogAuditDbAdaptor(); + auditDbAdaptor = new MongoDBAdaptorFactory(configuration, new IOManagerFactory()).getCatalogAuditDbAdaptor(); } @Test diff --git a/opencga-catalog/src/test/java/org/opencb/opencga/catalog/db/mongodb/FileMongoDBAdaptorTest.java b/opencga-catalog/src/test/java/org/opencb/opencga/catalog/db/mongodb/FileMongoDBAdaptorTest.java index 4321ec735ee..0c2dda0a32e 100644 --- a/opencga-catalog/src/test/java/org/opencb/opencga/catalog/db/mongodb/FileMongoDBAdaptorTest.java +++ b/opencga-catalog/src/test/java/org/opencb/opencga/catalog/db/mongodb/FileMongoDBAdaptorTest.java @@ -181,30 +181,6 @@ public void modifyFileTest() throws CatalogDBException, IOException, CatalogPara assertEquals(file.getStats(), new LinkedHashMap()); } - @Test - public void renameFileTest() throws CatalogDBException, CatalogParameterException, CatalogAuthorizationException { - String newName = "newFile.bam"; - String parentPath = "data/"; - long fileId = catalogFileDBAdaptor.getId(user3.getProjects().get(0).getStudies().get(0).getUid(), "data/file.vcf"); - System.out.println(catalogFileDBAdaptor.rename(fileId, parentPath + newName, "", null)); - - File file = catalogFileDBAdaptor.get(fileId, null).first(); - assertEquals(file.getName(), newName); - assertEquals(file.getPath(), parentPath + newName); - - try { - catalogFileDBAdaptor.rename(-1, "noFile", "", null); - fail("error: expected \"file not found\"exception"); - } catch (CatalogDBException e) { - System.out.println("correct exception: " + e); - } - - long folderId = catalogFileDBAdaptor.getId(user3.getProjects().get(0).getStudies().get(0).getUid(), "data/"); - String folderName = "folderName"; - catalogFileDBAdaptor.rename(folderId, folderName, "", null); - assertTrue(catalogFileDBAdaptor.get(fileId, null).first().getPath().equals(folderName + "/" + newName)); - } - @Test public void includeFields() throws CatalogDBException, CatalogParameterException, CatalogAuthorizationException { DataResult fileDataResult = catalogFileDBAdaptor.get(7, diff --git a/opencga-catalog/src/test/java/org/opencb/opencga/catalog/db/mongodb/MongoDBAdaptorTest.java b/opencga-catalog/src/test/java/org/opencb/opencga/catalog/db/mongodb/MongoDBAdaptorTest.java index ee8d9848e20..e88aeb2a0af 100644 --- a/opencga-catalog/src/test/java/org/opencb/opencga/catalog/db/mongodb/MongoDBAdaptorTest.java +++ b/opencga-catalog/src/test/java/org/opencb/opencga/catalog/db/mongodb/MongoDBAdaptorTest.java @@ -38,6 +38,7 @@ import org.opencb.opencga.catalog.exceptions.CatalogDBException; import org.opencb.opencga.catalog.exceptions.CatalogException; import org.opencb.opencga.catalog.exceptions.CatalogParameterException; +import org.opencb.opencga.catalog.io.IOManagerFactory; import org.opencb.opencga.core.common.PasswordUtils; import org.opencb.opencga.core.common.TimeUtils; import org.opencb.opencga.core.config.Admin; @@ -126,7 +127,7 @@ public void before() throws IOException, CatalogException { .setAlgorithm("HS256") .setSecretKey(PasswordUtils.getStrongRandomPassword(JwtManager.SECRET_KEY_MIN_LENGTH)) ); - catalogDBAdaptor = new MongoDBAdaptorFactory(configuration); + catalogDBAdaptor = new MongoDBAdaptorFactory(configuration, new IOManagerFactory()); catalogUserDBAdaptor = catalogDBAdaptor.getCatalogUserDBAdaptor(); catalogStudyDBAdaptor = catalogDBAdaptor.getCatalogStudyDBAdaptor(); catalogProjectDBAdaptor = catalogDBAdaptor.getCatalogProjectDbAdaptor(); diff --git a/opencga-catalog/src/test/java/org/opencb/opencga/catalog/managers/CatalogManagerExternalResource.java b/opencga-catalog/src/test/java/org/opencb/opencga/catalog/managers/CatalogManagerExternalResource.java index 2e79d7a0151..e717f074fe0 100644 --- a/opencga-catalog/src/test/java/org/opencb/opencga/catalog/managers/CatalogManagerExternalResource.java +++ b/opencga-catalog/src/test/java/org/opencb/opencga/catalog/managers/CatalogManagerExternalResource.java @@ -27,6 +27,7 @@ import org.opencb.opencga.catalog.auth.authentication.JwtManager; import org.opencb.opencga.catalog.db.mongodb.MongoDBAdaptorFactory; import org.opencb.opencga.catalog.exceptions.CatalogException; +import org.opencb.opencga.catalog.io.IOManagerFactory; import org.opencb.opencga.core.common.PasswordUtils; import org.opencb.opencga.core.common.TimeUtils; import org.opencb.opencga.core.common.UriUtils; @@ -132,7 +133,7 @@ public ObjectMapper generateNewObjectMapper() { } public static void clearCatalog(Configuration configuration) throws CatalogException, URISyntaxException { - try (MongoDBAdaptorFactory dbAdaptorFactory = new MongoDBAdaptorFactory(configuration)) { + try (MongoDBAdaptorFactory dbAdaptorFactory = new MongoDBAdaptorFactory(configuration, new IOManagerFactory())) { for (String collection : MongoDBAdaptorFactory.COLLECTIONS_LIST) { dbAdaptorFactory.getMongoDataStore().getCollection(collection).remove(new Document(), QueryOptions.empty()); } diff --git a/opencga-catalog/src/test/java/org/opencb/opencga/catalog/managers/FileManagerTest.java b/opencga-catalog/src/test/java/org/opencb/opencga/catalog/managers/FileManagerTest.java index c6c8dc91c61..a0517b1294a 100644 --- a/opencga-catalog/src/test/java/org/opencb/opencga/catalog/managers/FileManagerTest.java +++ b/opencga-catalog/src/test/java/org/opencb/opencga/catalog/managers/FileManagerTest.java @@ -31,7 +31,10 @@ import org.opencb.opencga.catalog.db.api.FileDBAdaptor; import org.opencb.opencga.catalog.db.api.SampleDBAdaptor; import org.opencb.opencga.catalog.db.api.StudyDBAdaptor; -import org.opencb.opencga.catalog.exceptions.*; +import org.opencb.opencga.catalog.exceptions.CatalogAuthorizationException; +import org.opencb.opencga.catalog.exceptions.CatalogDBException; +import org.opencb.opencga.catalog.exceptions.CatalogException; +import org.opencb.opencga.catalog.exceptions.CatalogIOException; import org.opencb.opencga.catalog.io.IOManager; import org.opencb.opencga.catalog.utils.Constants; import org.opencb.opencga.catalog.utils.ParamUtils; @@ -62,7 +65,8 @@ import java.util.concurrent.atomic.AtomicInteger; import java.util.stream.Collectors; -import static org.hamcrest.CoreMatchers.*; +import static org.hamcrest.CoreMatchers.hasItem; +import static org.hamcrest.CoreMatchers.not; import static org.junit.Assert.*; /** @@ -649,42 +653,131 @@ public void testLinkFilePassingNoDirectoryPath() throws CatalogException, URISyn } @Test - public void changeNameTest() throws CatalogException { - // Link VCF file. This VCF file will automatically create sample NA19600 - String vcfFile = getClass().getResource("/biofiles/variant-test-file.vcf.gz").getFile(); - catalogManager.getFileManager().link(studyFqn, new FileLinkParams(vcfFile, "data/", "", "", null, null, null, null, null), true, token); + public void testMoveFiles() throws CatalogException { + // Generate data set + catalogManager.getFileManager().create(studyFqn, new FileCreateParams().setType(File.Type.DIRECTORY).setPath("A/B/C/D/"), true, token); + catalogManager.getFileManager().create(studyFqn, new FileCreateParams().setType(File.Type.FILE).setPath("A/B/C/hello.txt").setContent("test"), false, token); + catalogManager.getFileManager().create(studyFqn, new FileCreateParams().setType(File.Type.FILE).setPath("A/B/C/hello2.txt").setContent("test"), false, token); + catalogManager.getFileManager().create(studyFqn, new FileCreateParams().setType(File.Type.FILE).setPath("A/B/C/D/hello.txt").setContent("test"), false, token); + catalogManager.getFileManager().create(studyFqn, new FileCreateParams().setType(File.Type.FILE).setPath("A/B/C/D/hello2.txt").setContent("test"), false, token); + catalogManager.getFileManager().create(studyFqn, new FileCreateParams().setType(File.Type.FILE).setPath("A/B/C/D/hello3.txt").setContent("test"), false, token); + + catalogManager.getSampleManager().create(studyFqn, new Sample().setId("sam1"), QueryOptions.empty(), token); + catalogManager.getSampleManager().create(studyFqn, new Sample().setId("sam2"), QueryOptions.empty(), token); + catalogManager.getSampleManager().create(studyFqn, new Sample().setId("sam3"), QueryOptions.empty(), token); + + Map fileMap = new HashMap<>(); + File file = catalogManager.getFileManager().update(studyFqn, "A/B/C/hello.txt", new FileUpdateParams().setSampleIds(Arrays.asList("sam1", "sam3")), INCLUDE_RESULT, token).first(); + fileMap.put(file.getUid(), file); + file = catalogManager.getFileManager().update(studyFqn, "A/B/C/hello2.txt", new FileUpdateParams().setSampleIds(Collections.singletonList("sam1")), INCLUDE_RESULT, token).first(); + fileMap.put(file.getUid(), file); + file = catalogManager.getFileManager().update(studyFqn, "A/B/C/D/hello.txt", new FileUpdateParams().setSampleIds(Arrays.asList("sam2", "sam3")), INCLUDE_RESULT, token).first(); + fileMap.put(file.getUid(), file); + file = catalogManager.getFileManager().update(studyFqn, "A/B/C/D/hello2.txt", new FileUpdateParams().setSampleIds(Collections.singletonList("sam2")), INCLUDE_RESULT, token).first(); + fileMap.put(file.getUid(), file); + file = catalogManager.getFileManager().update(studyFqn, "A/B/C/D/hello3.txt", new FileUpdateParams().setSampleIds(Collections.singletonList("sam3")), INCLUDE_RESULT, token).first(); + fileMap.put(file.getUid(), file); + + Map sampleVersionMap = new HashMap<>(); + sampleVersionMap.put("sam1", 3); + sampleVersionMap.put("sam2", 3); + sampleVersionMap.put("sam3", 4); + + OpenCGAResult sampleResults = catalogManager.getSampleManager().get(studyFqn, Arrays.asList("sam1", "sam2", "sam3"), QueryOptions.empty(), token); + assertEquals(3, sampleResults.getNumResults()); + for (Sample sample : sampleResults.getResults()) { + assertEquals(sampleVersionMap.get(sample.getId()).intValue(), sample.getVersion()); + List fileList = new ArrayList<>(); + for (File tmpFile : fileMap.values()) { + if (tmpFile.getSampleIds().contains(sample.getId())) { + fileList.add(tmpFile.getId()); + } + } + assertArrayEquals(fileList.toArray(), sample.getFileIds().toArray()); + } - Query query = new Query(SampleDBAdaptor.QueryParams.FILE_IDS.key(), "variant-test-file.vcf.gz"); - QueryOptions options = new QueryOptions(QueryOptions.INCLUDE, SampleDBAdaptor.QueryParams.FILE_IDS.key()); - OpenCGAResult sampleResult = catalogManager.getSampleManager().search(studyFqn, query, options, token); - assertEquals(4, sampleResult.getNumResults()); - for (Sample sample : sampleResult.getResults()) { - assertEquals(1, sample.getFileIds().size()); - assertEquals("data:variant-test-file.vcf.gz", sample.getFileIds().get(0)); - assertEquals(1, sample.getVersion()); + // Expected path after moving (not yet moved) + CatalogException catalogException = assertThrows(CatalogException.class, () -> catalogManager.getFileManager().get(studyFqn, Arrays.asList("A/C/D", "A/C/hello.txt", "A/C/hello2.txt", "A/C/D/hello.txt", "A/C/D/hello2.txt", "A/C/D/hello3.txt"), FileManager.INCLUDE_FILE_URI_PATH, token)); + assertTrue(catalogException.getMessage().contains("not found")); + + // Path before moving + OpenCGAResult beforeResult = catalogManager.getFileManager().get(studyFqn, Arrays.asList("A/B/C/D/", "A/B/C/hello.txt", "A/B/C/hello2.txt", "A/B/C/D/hello.txt", "A/B/C/D/hello2.txt", "A/B/C/D/hello3.txt"), QueryOptions.empty(), token); + assertEquals(6, beforeResult.getNumResults()); + for (File tmpFile : beforeResult.getResults()) { + assertNotNull(tmpFile.getUri()); + assertTrue(Files.exists(Paths.get(tmpFile.getUri()))); + if (fileMap.containsKey(tmpFile.getUid())) { + File ffile = fileMap.get(tmpFile.getUid()); + System.out.println("Checking samples for file '" + tmpFile.getPath() + "'"); + assertEquals(ffile.getSampleIds().size(), tmpFile.getSampleIds().size()); + assertArrayEquals(ffile.getSampleIds().toArray(), tmpFile.getSampleIds().toArray()); + } } - // Rename file - FileUpdateParams updateParams = new FileUpdateParams().setName("variant_test.vcf.gz"); - catalogManager.getFileManager().update(studyFqn, "variant-test-file.vcf.gz", updateParams, null, token); + // Move folder + catalogManager.getFileManager().move(studyFqn, "A/B/C/", "A/C/", QueryOptions.empty(), token); + + // Path before moving + catalogException = assertThrows(CatalogException.class, () -> catalogManager.getFileManager().get(studyFqn, Arrays.asList("A/B/C/D/", "A/B/C/hello.txt", "A/B/C/hello2.txt", "A/B/C/D/hello.txt", "A/B/C/D/hello2.txt", "A/B/C/D/hello3.txt"), FileManager.INCLUDE_FILE_URI_PATH, token)); + assertTrue(catalogException.getMessage().contains("not found")); + + Map afterMoveFileMap = new HashMap<>(); + + // Path after moving + OpenCGAResult afterResult = catalogManager.getFileManager().get(studyFqn, Arrays.asList("A/C/D/", "A/C/hello.txt", "A/C/hello2.txt", "A/C/D/hello.txt", "A/C/D/hello2.txt", "A/C/D/hello3.txt"), QueryOptions.empty(), token); + assertEquals(6, afterResult.getNumResults()); + for (int i = 0; i < afterResult.getResults().size(); i++) { + File beforeMoving = beforeResult.getResults().get(i); + File afterMoving = afterResult.getResults().get(i); + assertNotNull(afterMoving.getUri()); + assertNotEquals("Found same URI. File/folder should have been moved", afterMoving.getUri(), beforeMoving.getUri()); + assertTrue(Files.exists(Paths.get(afterMoving.getUri()))); + assertTrue(Files.notExists(Paths.get(beforeMoving.getUri()))); + + if (fileMap.containsKey(afterMoving.getUid())) { + File ffile = fileMap.get(afterMoving.getUid()); + System.out.println("Checking samples for file '" + afterMoving.getPath() + "'"); + assertEquals(ffile.getSampleIds().size(), afterMoving.getSampleIds().size()); + assertArrayEquals(ffile.getSampleIds().toArray(), afterMoving.getSampleIds().toArray()); + afterMoveFileMap.put(afterMoving.getUid(), afterMoving); + } + } - assertThrows("not found", CatalogException.class, () -> catalogManager.getFileManager().get(studyFqn, "variant-test-file.vcf.gz", null, token)); - File file = catalogManager.getFileManager().get(studyFqn, updateParams.getName(), FileManager.INCLUDE_FILE_URI_PATH, token).first(); - assertEquals("data:" + updateParams.getName(), file.getId()); - assertEquals("data/" + updateParams.getName(), file.getPath()); - assertEquals(updateParams.getName(), file.getName()); + // Check modifications in sample + sampleResults = catalogManager.getSampleManager().get(studyFqn, Arrays.asList("sam1", "sam2", "sam3"), QueryOptions.empty(), token); + assertEquals(3, sampleResults.getNumResults()); + for (Sample sample : sampleResults.getResults()) { + assertEquals(sampleVersionMap.get(sample.getId()).intValue() + 1, sample.getVersion()); + List fileList = new ArrayList<>(); + for (File tmpFile : afterMoveFileMap.values()) { + if (tmpFile.getSampleIds().contains(sample.getId())) { + fileList.add(tmpFile.getId()); + } + } + assertArrayEquals(fileList.toArray(), sample.getFileIds().toArray()); + } - sampleResult = catalogManager.getSampleManager().search(studyFqn, query, options, token); - assertEquals(0, sampleResult.getNumResults()); + // Attempt to move folder to folder in use + CatalogDBException catalogDBException = assertThrows(CatalogDBException.class, () -> catalogManager.getFileManager().move(studyFqn, "A/C/", "A/B/", QueryOptions.empty(), token)); + assertTrue(catalogDBException.getMessage().contains("exists")); - query = new Query(SampleDBAdaptor.QueryParams.FILE_IDS.key(), updateParams.getName()); - sampleResult = catalogManager.getSampleManager().search(studyFqn, query, options, token); - assertEquals(4, sampleResult.getNumResults()); - for (Sample sample : sampleResult.getResults()) { - assertEquals(1, sample.getFileIds().size()); - assertEquals("data:" + updateParams.getName(), sample.getFileIds().get(0)); - assertEquals(2, sample.getVersion()); - } + // Rename file + catalogManager.getFileManager().move(studyFqn, "A/C/D/hello3.txt", "A/C/D/otherName.txt", QueryOptions.empty(), token); + assertThrows(CatalogException.class, () -> catalogManager.getFileManager().get(studyFqn, "A/C/D/hello3.txt", QueryOptions.empty(), token)); + file = catalogManager.getFileManager().get(studyFqn, "A/C/D/otherName.txt", QueryOptions.empty(), token).first(); + assertTrue(file.getId().endsWith(":otherName.txt")); + assertTrue(file.getPath().endsWith("/otherName.txt")); + assertTrue(file.getUri().toString().endsWith("/otherName.txt")); + assertEquals("otherName.txt", file.getName()); + assertTrue(Files.exists(Paths.get(file.getUri()))); + // Check samples + assertEquals(1, file.getSampleIds().size()); + assertTrue(file.getSampleIds().contains("sam3")); + + Sample sample3 = catalogManager.getSampleManager().get(studyFqn, "sam3", QueryOptions.empty(), token).first(); + assertEquals(6, sample3.getVersion()); + assertEquals(3, sample3.getFileIds().size()); + assertTrue(sample3.getFileIds().contains(file.getId())); } @Test @@ -1394,44 +1487,6 @@ public void testGetTreeViewMoreThanOneFile() throws CatalogException { assertEquals(2, fileTree.getNumResults()); } - @Test - public void renameFileTest() throws CatalogException { - DataResult queryResult1 = fileManager.create(studyFqn, new FileCreateParams() - .setPath("data/file.txt") - .setType(File.Type.FILE) - .setContent(RandomStringUtils.randomAlphanumeric(200)), - true, token); - assertEquals(1, queryResult1.getNumResults()); - - DataResult queryResult = fileManager.create(studyFqn, new FileCreateParams() - .setPath("data/nested/folder/file2.txt") - .setType(File.Type.FILE) - .setContent(RandomStringUtils.randomAlphanumeric(200)), - true, token); - assertEquals(1, queryResult.getNumResults()); - - fileManager.rename(studyFqn, "data/nested/", "nested2", token); - Set paths = fileManager.search(studyFqn, new Query(), new QueryOptions(), token) - .getResults() - .stream().map(File::getPath).collect(Collectors.toSet()); - - assertTrue(paths.contains("data/nested2/")); - assertFalse(paths.contains("data/nested/")); - assertTrue(paths.contains("data/nested2/folder/")); - assertTrue(paths.contains("data/nested2/folder/file2.txt")); - assertTrue(paths.contains("data/file.txt")); - - fileManager.rename(studyFqn, "data/", "Data", token); - paths = fileManager.search(studyFqn, new Query(), new QueryOptions(), token).getResults() - .stream().map(File::getPath).collect(Collectors.toSet()); - - assertTrue(paths.contains("Data/")); - assertTrue(paths.contains("Data/file.txt")); - assertTrue(paths.contains("Data/nested2/")); - assertTrue(paths.contains("Data/nested2/folder/")); - assertTrue(paths.contains("Data/nested2/folder/file2.txt")); - } - @Test public void getFileIdByString() throws CatalogException { StudyAclParams aclParams = new StudyAclParams("", "analyst"); @@ -1455,28 +1510,6 @@ public void getFileIdByString() throws CatalogException { System.out.println(fileId); } - @Test - public void renameFileEmptyName() throws CatalogException { - thrown.expect(CatalogParameterException.class); - thrown.expectMessage(containsString("null or empty")); - fileManager.rename(studyFqn, "data/", "", token); - } - - @Test - public void renameFileSlashInName() throws CatalogException { - thrown.expect(CatalogParameterException.class); - fileManager.rename(studyFqn, "data/", "my/folder", token); - } - - @Test - public void renameFileAlreadyExists() throws CatalogException { - fileManager.createFolder(studyFqn, "analysis/", false, "", new QueryOptions(), - token); - thrown.expect(CatalogException.class); - thrown.expectMessage("already exists"); - fileManager.rename(studyFqn, "data/", "analysis", token); - } - @Test public void searchFileTest() throws CatalogException { Query query; diff --git a/opencga-catalog/src/test/java/org/opencb/opencga/catalog/migration/MigrationManagerTest.java b/opencga-catalog/src/test/java/org/opencb/opencga/catalog/migration/MigrationManagerTest.java index 102bc501caa..2f688a81fba 100644 --- a/opencga-catalog/src/test/java/org/opencb/opencga/catalog/migration/MigrationManagerTest.java +++ b/opencga-catalog/src/test/java/org/opencb/opencga/catalog/migration/MigrationManagerTest.java @@ -131,7 +131,8 @@ protected void run() throws Exception { @Before public void setUp() throws Exception { super.setUp(); - try (MongoDBAdaptorFactory mongoDBAdaptorFactory = new MongoDBAdaptorFactory(catalogManager.getConfiguration())) { + try (MongoDBAdaptorFactory mongoDBAdaptorFactory = new MongoDBAdaptorFactory(catalogManager.getConfiguration(), + catalogManager.getIoManagerFactory())) { mongoDBAdaptorFactory.getMongoDataStore() .getCollection(MongoDBAdaptorFactory.MIGRATION_COLLECTION) .remove(new Document(), new QueryOptions(MongoDBCollection.MULTI, true)); diff --git a/opencga-core/src/main/java/org/opencb/opencga/core/models/common/Enums.java b/opencga-core/src/main/java/org/opencb/opencga/core/models/common/Enums.java index 764a07b409c..c26bfe647a0 100644 --- a/opencga-core/src/main/java/org/opencb/opencga/core/models/common/Enums.java +++ b/opencga-core/src/main/java/org/opencb/opencga/core/models/common/Enums.java @@ -168,6 +168,7 @@ public enum Action { GREP, TREE, DOWNLOAD_AND_REGISTER, + MOVE, MOVE_AND_REGISTER, VISIT, diff --git a/opencga-core/src/main/java/org/opencb/opencga/core/models/file/FileMoveParams.java b/opencga-core/src/main/java/org/opencb/opencga/core/models/file/FileMoveParams.java new file mode 100644 index 00000000000..2ab407a02ef --- /dev/null +++ b/opencga-core/src/main/java/org/opencb/opencga/core/models/file/FileMoveParams.java @@ -0,0 +1,18 @@ +package org.opencb.opencga.core.models.file; + +public class FileMoveParams { + + private String path; + + public FileMoveParams() { + } + + public String getPath() { + return path; + } + + public FileMoveParams setPath(String path) { + this.path = path; + return this; + } +} diff --git a/opencga-core/src/main/java/org/opencb/opencga/core/models/file/FileUpdateParams.java b/opencga-core/src/main/java/org/opencb/opencga/core/models/file/FileUpdateParams.java index 38e6d7ad04a..4dc06f9898f 100644 --- a/opencga-core/src/main/java/org/opencb/opencga/core/models/file/FileUpdateParams.java +++ b/opencga-core/src/main/java/org/opencb/opencga/core/models/file/FileUpdateParams.java @@ -30,14 +30,12 @@ public class FileUpdateParams { - private String name; private String description; private String creationDate; private String modificationDate; private List sampleIds; - private String checksum; private File.Format format; private File.Bioformat bioformat; private Software software; @@ -47,8 +45,6 @@ public class FileUpdateParams { private List relatedFiles; - private Long size; - private StatusParams status; private List annotationSets; private FileQualityControl qualityControl; @@ -58,24 +54,21 @@ public class FileUpdateParams { public FileUpdateParams() { } - public FileUpdateParams(String name, String description, String creationDate, String modificationDate, List sampleIds, - String checksum, File.Format format, File.Bioformat bioformat, Software software, FileExperiment experiment, - List tags, SmallFileInternal internal, Long size, List relatedFiles, + public FileUpdateParams(String description, String creationDate, String modificationDate, List sampleIds, + File.Format format, File.Bioformat bioformat, Software software, FileExperiment experiment, + List tags, SmallFileInternal internal, List relatedFiles, StatusParams status, List annotationSets, FileQualityControl qualityControl, Map stats, Map attributes) { - this.name = name; this.description = description; this.creationDate = creationDate; this.modificationDate = modificationDate; this.sampleIds = sampleIds; - this.checksum = checksum; this.format = format; this.bioformat = bioformat; this.software = software; this.experiment = experiment; this.tags = tags; this.internal = internal; - this.size = size; this.relatedFiles = relatedFiles; this.status = status; this.annotationSets = annotationSets; @@ -103,12 +96,10 @@ public ObjectMap getUpdateMap() throws JsonProcessingException { @Override public String toString() { final StringBuilder sb = new StringBuilder("FileUpdateParams{"); - sb.append("name='").append(name).append('\''); - sb.append(", description='").append(description).append('\''); + sb.append("description='").append(description).append('\''); sb.append(", creationDate='").append(creationDate).append('\''); sb.append(", modificationDate='").append(modificationDate).append('\''); sb.append(", sampleIds=").append(sampleIds); - sb.append(", checksum='").append(checksum).append('\''); sb.append(", format=").append(format); sb.append(", bioformat=").append(bioformat); sb.append(", software=").append(software); @@ -116,7 +107,6 @@ public String toString() { sb.append(", tags=").append(tags); sb.append(", internal=").append(internal); sb.append(", relatedFiles=").append(relatedFiles); - sb.append(", size=").append(size); sb.append(", status=").append(status); sb.append(", annotationSets=").append(annotationSets); sb.append(", qualityControl=").append(qualityControl); @@ -126,15 +116,6 @@ public String toString() { return sb.toString(); } - public String getName() { - return name; - } - - public FileUpdateParams setName(String name) { - this.name = name; - return this; - } - public String getDescription() { return description; } @@ -171,15 +152,6 @@ public FileUpdateParams setSampleIds(List sampleIds) { return this; } - public String getChecksum() { - return checksum; - } - - public FileUpdateParams setChecksum(String checksum) { - this.checksum = checksum; - return this; - } - public File.Format getFormat() { return format; } @@ -234,15 +206,6 @@ public FileUpdateParams setExperiment(FileExperiment experiment) { return this; } - public Long getSize() { - return size; - } - - public FileUpdateParams setSize(Long size) { - this.size = size; - return this; - } - public List getRelatedFiles() { return relatedFiles; } diff --git a/opencga-core/src/main/java/org/opencb/opencga/core/tools/result/ExecutionResult.java b/opencga-core/src/main/java/org/opencb/opencga/core/tools/result/ExecutionResult.java index 92c394ec25b..3d73c2e81dd 100644 --- a/opencga-core/src/main/java/org/opencb/opencga/core/tools/result/ExecutionResult.java +++ b/opencga-core/src/main/java/org/opencb/opencga/core/tools/result/ExecutionResult.java @@ -33,7 +33,6 @@ public class ExecutionResult { description = FieldConstants.GENERIC_ID_DESCRIPTION) private String id; - @DataField(id = "executor", indexed = true, description = FieldConstants.EXECUTION_RESULT_EXECUTION_INFO) private ExecutorInfo executor; @@ -50,7 +49,6 @@ public class ExecutionResult { description = FieldConstants.EXECUTION_RESULT_STATUS) private Status status; - @DataField(id = "externalFiles", indexed = true, description = FieldConstants.EXECUTION_RESULT_EXTERNAL_FILES) private List externalFiles; diff --git a/opencga-core/src/test/java/org/opencb/opencga/core/config/ConfigurationTest.java b/opencga-core/src/test/java/org/opencb/opencga/core/config/ConfigurationTest.java index 06af4d5d50a..a617f0049b0 100644 --- a/opencga-core/src/test/java/org/opencb/opencga/core/config/ConfigurationTest.java +++ b/opencga-core/src/test/java/org/opencb/opencga/core/config/ConfigurationTest.java @@ -16,13 +16,15 @@ package org.opencb.opencga.core.config; +import org.apache.commons.lang3.StringUtils; import org.junit.Test; import org.junit.experimental.categories.Category; import org.opencb.opencga.core.testclassification.duration.ShortTests; -import java.io.*; -import java.net.URL; -import java.nio.charset.Charset; +import java.io.FileOutputStream; +import java.io.IOException; +import java.nio.file.Path; +import java.nio.file.Paths; import java.util.*; /** @@ -31,6 +33,67 @@ @Category(ShortTests.class) public class ConfigurationTest { + @Test + public void test() { + String path1 = "a/b/c.txt"; + String path2 = "a/b/c/"; + String path3 = "p.txt"; + + System.out.println(path1 + " ---- " + getParentPath(path1)); + System.out.println(path2 + " ---- " + getParentPath(path2)); + System.out.println(path3 + " ---- " + getParentPath(path3)); + + System.out.println(path1 + " ---- " + calculateAllPossiblePaths(path1)); + System.out.println(path2 + " ---- " + calculateAllPossiblePaths(path2)); + System.out.println(path3 + " ---- " + calculateAllPossiblePaths(path3)); + System.out.println("'' ---- " + calculateAllPossiblePaths("")); + + System.out.println(path1 + " ---- " + getFileName(path1)); + System.out.println(path2 + " ---- " + getFileName(path2)); + System.out.println(path3 + " ---- " + getFileName(path3)); + System.out.println("'' ---- " + getFileName("")); + + } + + String getParentPath(String strPath) { + Path path = Paths.get(strPath); + Path parent = path.getParent(); + if (parent != null) { + return parent.toString() + "/"; + } else { + return ""; + } + } + + String getFileName(String strPath) { + if (StringUtils.isEmpty(strPath)) { + return "."; + } + return Paths.get(strPath).getFileName().toString(); + } + + public static List calculateAllPossiblePaths(String filePath) { + if (StringUtils.isEmpty(filePath) || "/".equals(filePath)) { + return Collections.singletonList(""); + } + StringBuilder pathBuilder = new StringBuilder(); + String[] split = filePath.split("/"); + List paths = new ArrayList<>(split.length + 1); + paths.add(""); //Add study root folder + //Add intermediate folders + //Do not add the last split, could be a file or a folder.. + //Depending on this, it could end with '/' or not. + for (int i = 0; i < split.length - 1; i++) { + String f = split[i]; + System.out.println(f); + pathBuilder = new StringBuilder(pathBuilder.toString()).append(f).append("/"); + paths.add(pathBuilder.toString()); + } + paths.add(filePath); //Add the file path + return paths; + } + + @Test public void testDefault() { Configuration configuration = new Configuration(); diff --git a/opencga-master/src/main/java/org/opencb/opencga/master/monitor/daemons/MonitorParentDaemon.java b/opencga-master/src/main/java/org/opencb/opencga/master/monitor/daemons/MonitorParentDaemon.java index 8fcd7a59c18..247b7a81534 100644 --- a/opencga-master/src/main/java/org/opencb/opencga/master/monitor/daemons/MonitorParentDaemon.java +++ b/opencga-master/src/main/java/org/opencb/opencga/master/monitor/daemons/MonitorParentDaemon.java @@ -50,7 +50,7 @@ public MonitorParentDaemon(int interval, String token, CatalogManager catalogMan this.catalogManager = catalogManager; this.token = token; logger = LoggerFactory.getLogger(this.getClass()); - dbAdaptorFactory = new MongoDBAdaptorFactory(catalogManager.getConfiguration()); + dbAdaptorFactory = new MongoDBAdaptorFactory(catalogManager.getConfiguration(), catalogManager.getIoManagerFactory()); ExecutorFactory executorFactory = new ExecutorFactory(catalogManager.getConfiguration()); this.batchExecutor = executorFactory.getExecutor(); } diff --git a/opencga-server/src/main/java/org/opencb/opencga/server/rest/FileWSServer.java b/opencga-server/src/main/java/org/opencb/opencga/server/rest/FileWSServer.java index 3c030b9ce64..893a4fea3d8 100644 --- a/opencga-server/src/main/java/org/opencb/opencga/server/rest/FileWSServer.java +++ b/opencga-server/src/main/java/org/opencb/opencga/server/rest/FileWSServer.java @@ -575,6 +575,27 @@ public Response updatePOST( } } + @POST + @Path("/{file}/move") + @ApiOperation(value = "Move file to a different path", response = File.class) + @ApiImplicitParams({ + @ApiImplicitParam(name = QueryOptions.INCLUDE, value = ParamConstants.INCLUDE_DESCRIPTION, + dataType = "string", paramType = "query"), + @ApiImplicitParam(name = QueryOptions.EXCLUDE, value = ParamConstants.EXCLUDE_DESCRIPTION, + dataType = "string", paramType = "query") + }) + public Response move( + @ApiParam(value = "File id, UUID or name.") @PathParam(value = "file") String fileIdStr, + @ApiParam(value = ParamConstants.STUDY_DESCRIPTION) @QueryParam(ParamConstants.STUDY_PARAM) String studyStr, + @ApiParam(name = "body", value = "Parameters to modify", required = true) FileMoveParams moveParams) { + try { + DataResult queryResult = fileManager.move(studyStr, fileIdStr, moveParams.getPath(), queryOptions, token); + return createOkResponse(queryResult); + } catch (Exception e) { + return createErrorResponse(e); + } + } + // @JsonIgnoreProperties({"status"}) // public static class FileUpdateParams extends org.opencb.opencga.core.models.file.FileUpdateParams { // } From 85ff3e4d4059afe3c7b1a5fbba9c43fbadd8b6ae Mon Sep 17 00:00:00 2001 From: JuanfeSanahuja Date: Fri, 8 Mar 2024 17:12:37 +0100 Subject: [PATCH 05/85] Prepare next release 2.12.4-SNAPSHOT --- opencga-analysis/pom.xml | 2 +- opencga-app/pom.xml | 2 +- opencga-catalog/pom.xml | 2 +- opencga-client/pom.xml | 2 +- opencga-clinical/pom.xml | 2 +- opencga-core/pom.xml | 2 +- opencga-master/pom.xml | 2 +- opencga-server/pom.xml | 2 +- opencga-storage/opencga-storage-app/pom.xml | 2 +- opencga-storage/opencga-storage-benchmark/pom.xml | 2 +- opencga-storage/opencga-storage-core/pom.xml | 2 +- .../opencga-storage-hadoop-core/pom.xml | 2 +- .../opencga-storage-hadoop-deps-emr6.1/pom.xml | 2 +- .../opencga-storage-hadoop-deps-hdp2.6/pom.xml | 2 +- .../opencga-storage-hadoop-deps-hdp3.1/pom.xml | 2 +- .../opencga-storage-hadoop-deps/pom.xml | 2 +- opencga-storage/opencga-storage-hadoop/pom.xml | 2 +- opencga-storage/opencga-storage-server/pom.xml | 2 +- opencga-storage/pom.xml | 2 +- opencga-test/pom.xml | 2 +- pom.xml | 14 +++++++------- 21 files changed, 27 insertions(+), 27 deletions(-) diff --git a/opencga-analysis/pom.xml b/opencga-analysis/pom.xml index 2f37a252831..8f1dbb61469 100644 --- a/opencga-analysis/pom.xml +++ b/opencga-analysis/pom.xml @@ -22,7 +22,7 @@ org.opencb.opencga opencga - 2.12.3 + 2.12.4-SNAPSHOT ../pom.xml diff --git a/opencga-app/pom.xml b/opencga-app/pom.xml index 469a78da211..3daac8c0301 100644 --- a/opencga-app/pom.xml +++ b/opencga-app/pom.xml @@ -22,7 +22,7 @@ org.opencb.opencga opencga - 2.12.3 + 2.12.4-SNAPSHOT ../pom.xml diff --git a/opencga-catalog/pom.xml b/opencga-catalog/pom.xml index 45841f053b8..7a4dd21139b 100644 --- a/opencga-catalog/pom.xml +++ b/opencga-catalog/pom.xml @@ -23,7 +23,7 @@ org.opencb.opencga opencga - 2.12.3 + 2.12.4-SNAPSHOT ../pom.xml diff --git a/opencga-client/pom.xml b/opencga-client/pom.xml index f83bc38566c..35402c7c932 100644 --- a/opencga-client/pom.xml +++ b/opencga-client/pom.xml @@ -22,7 +22,7 @@ org.opencb.opencga opencga - 2.12.3 + 2.12.4-SNAPSHOT ../pom.xml diff --git a/opencga-clinical/pom.xml b/opencga-clinical/pom.xml index c940323e6c3..3ae7d4f552b 100644 --- a/opencga-clinical/pom.xml +++ b/opencga-clinical/pom.xml @@ -5,7 +5,7 @@ org.opencb.opencga opencga - 2.12.3 + 2.12.4-SNAPSHOT ../pom.xml 4.0.0 diff --git a/opencga-core/pom.xml b/opencga-core/pom.xml index d604a47f8a7..7d949bb6f58 100644 --- a/opencga-core/pom.xml +++ b/opencga-core/pom.xml @@ -22,7 +22,7 @@ org.opencb.opencga opencga - 2.12.3 + 2.12.4-SNAPSHOT ../pom.xml diff --git a/opencga-master/pom.xml b/opencga-master/pom.xml index b73a4997bde..4df3d66a007 100644 --- a/opencga-master/pom.xml +++ b/opencga-master/pom.xml @@ -22,7 +22,7 @@ opencga org.opencb.opencga - 2.12.3 + 2.12.4-SNAPSHOT ../pom.xml diff --git a/opencga-server/pom.xml b/opencga-server/pom.xml index cc283eec5b3..326718f8022 100644 --- a/opencga-server/pom.xml +++ b/opencga-server/pom.xml @@ -22,7 +22,7 @@ org.opencb.opencga opencga - 2.12.3 + 2.12.4-SNAPSHOT ../pom.xml diff --git a/opencga-storage/opencga-storage-app/pom.xml b/opencga-storage/opencga-storage-app/pom.xml index 2ac713e617f..2823f273f28 100644 --- a/opencga-storage/opencga-storage-app/pom.xml +++ b/opencga-storage/opencga-storage-app/pom.xml @@ -22,7 +22,7 @@ org.opencb.opencga opencga-storage - 2.12.3 + 2.12.4-SNAPSHOT ../pom.xml diff --git a/opencga-storage/opencga-storage-benchmark/pom.xml b/opencga-storage/opencga-storage-benchmark/pom.xml index a7165736683..cc328a5fdd8 100644 --- a/opencga-storage/opencga-storage-benchmark/pom.xml +++ b/opencga-storage/opencga-storage-benchmark/pom.xml @@ -22,7 +22,7 @@ opencga-storage org.opencb.opencga - 2.12.3 + 2.12.4-SNAPSHOT ../pom.xml diff --git a/opencga-storage/opencga-storage-core/pom.xml b/opencga-storage/opencga-storage-core/pom.xml index de4c0fa391f..00bf4226afd 100644 --- a/opencga-storage/opencga-storage-core/pom.xml +++ b/opencga-storage/opencga-storage-core/pom.xml @@ -22,7 +22,7 @@ org.opencb.opencga opencga-storage - 2.12.3 + 2.12.4-SNAPSHOT ../pom.xml diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/pom.xml b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/pom.xml index 57b93f43638..453935bf26c 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/pom.xml +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/pom.xml @@ -23,7 +23,7 @@ org.opencb.opencga opencga-storage-hadoop - 2.12.3 + 2.12.4-SNAPSHOT ../pom.xml diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-deps/opencga-storage-hadoop-deps-emr6.1/pom.xml b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-deps/opencga-storage-hadoop-deps-emr6.1/pom.xml index 187bcf1ebca..9df46c71579 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-deps/opencga-storage-hadoop-deps-emr6.1/pom.xml +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-deps/opencga-storage-hadoop-deps-emr6.1/pom.xml @@ -22,7 +22,7 @@ org.opencb.opencga opencga-storage-hadoop-deps - 2.12.3 + 2.12.4-SNAPSHOT ../pom.xml diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-deps/opencga-storage-hadoop-deps-hdp2.6/pom.xml b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-deps/opencga-storage-hadoop-deps-hdp2.6/pom.xml index 3d9770ca8b6..64a1da9403f 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-deps/opencga-storage-hadoop-deps-hdp2.6/pom.xml +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-deps/opencga-storage-hadoop-deps-hdp2.6/pom.xml @@ -22,7 +22,7 @@ org.opencb.opencga opencga-storage-hadoop-deps - 2.12.3 + 2.12.4-SNAPSHOT ../pom.xml diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-deps/opencga-storage-hadoop-deps-hdp3.1/pom.xml b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-deps/opencga-storage-hadoop-deps-hdp3.1/pom.xml index 1dcdfd8806f..b1eae85ecec 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-deps/opencga-storage-hadoop-deps-hdp3.1/pom.xml +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-deps/opencga-storage-hadoop-deps-hdp3.1/pom.xml @@ -22,7 +22,7 @@ org.opencb.opencga opencga-storage-hadoop-deps - 2.12.3 + 2.12.4-SNAPSHOT ../pom.xml diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-deps/pom.xml b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-deps/pom.xml index a2f013cecee..164bbcc0560 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-deps/pom.xml +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-deps/pom.xml @@ -50,7 +50,7 @@ org.opencb.opencga opencga-storage-hadoop - 2.12.3 + 2.12.4-SNAPSHOT ../pom.xml diff --git a/opencga-storage/opencga-storage-hadoop/pom.xml b/opencga-storage/opencga-storage-hadoop/pom.xml index dfcc535c552..6e0196b0eb8 100644 --- a/opencga-storage/opencga-storage-hadoop/pom.xml +++ b/opencga-storage/opencga-storage-hadoop/pom.xml @@ -28,7 +28,7 @@ org.opencb.opencga opencga-storage - 2.12.3 + 2.12.4-SNAPSHOT ../pom.xml diff --git a/opencga-storage/opencga-storage-server/pom.xml b/opencga-storage/opencga-storage-server/pom.xml index 7fa16cd7e44..9ec6f2f1ab3 100644 --- a/opencga-storage/opencga-storage-server/pom.xml +++ b/opencga-storage/opencga-storage-server/pom.xml @@ -22,7 +22,7 @@ org.opencb.opencga opencga-storage - 2.12.3 + 2.12.4-SNAPSHOT ../pom.xml diff --git a/opencga-storage/pom.xml b/opencga-storage/pom.xml index 1b9aa4d14f1..0c2ccaae662 100644 --- a/opencga-storage/pom.xml +++ b/opencga-storage/pom.xml @@ -22,7 +22,7 @@ org.opencb.opencga opencga - 2.12.3 + 2.12.4-SNAPSHOT ../pom.xml diff --git a/opencga-test/pom.xml b/opencga-test/pom.xml index 9e45f063d59..469922d6d88 100644 --- a/opencga-test/pom.xml +++ b/opencga-test/pom.xml @@ -24,7 +24,7 @@ org.opencb.opencga opencga - 2.12.3 + 2.12.4-SNAPSHOT ../pom.xml diff --git a/pom.xml b/pom.xml index d87ec40c887..6421b21012a 100644 --- a/pom.xml +++ b/pom.xml @@ -22,7 +22,7 @@ org.opencb.opencga opencga - 2.12.3 + 2.12.4-SNAPSHOT pom OpenCGA @@ -43,12 +43,12 @@ - 2.12.3 - 2.12.3 - 5.8.2 - 2.12.1 - 4.12.0 - 2.12.3 + 2.12.4_dev + 2.12.4_dev + 5.8.3-SNAPSHOT + 2.12.2-SNAPSHOT + 4.12.1-SNAPSHOT + 2.12.4-SNAPSHOT 0.2.0 2.11.4 From 060c26fe6a43b1db8c9fa6203866622f60a3456d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joaqu=C3=ADn=20T=C3=A1rraga=20Gim=C3=A9nez?= Date: Thu, 14 Mar 2024 09:29:45 +0100 Subject: [PATCH 06/85] analysis: improve alignment and coverage index by taking into account the blob storage behaviour #TASK-5858 --- .../alignment/AlignmentCoverageAnalysis.java | 16 +++++++++------- .../alignment/AlignmentIndexOperation.java | 16 +++++++++------- 2 files changed, 18 insertions(+), 14 deletions(-) diff --git a/opencga-analysis/src/main/java/org/opencb/opencga/analysis/alignment/AlignmentCoverageAnalysis.java b/opencga-analysis/src/main/java/org/opencb/opencga/analysis/alignment/AlignmentCoverageAnalysis.java index 2712d22b8f3..b089541591a 100644 --- a/opencga-analysis/src/main/java/org/opencb/opencga/analysis/alignment/AlignmentCoverageAnalysis.java +++ b/opencga-analysis/src/main/java/org/opencb/opencga/analysis/alignment/AlignmentCoverageAnalysis.java @@ -168,20 +168,22 @@ protected void run() throws Exception { + ") was not create, please, check log files."); } - // Try to copy the BW file into the BAM file directory + // Try to move the BW file into the BAM file directory + boolean moveSuccessful = false; Path targetPath = Paths.get(bamCatalogFile.getUri()).getParent().resolve(bwPath.getFileName()); try { - Files.move(bwPath, targetPath); + Path movedPath = Files.move(bwPath, targetPath); + moveSuccessful = targetPath.equals(movedPath); } catch (Exception e) { - // Do nothing - logger.info("Moving from {} to {}: {}", bwPath, targetPath, e.getMessage()); + // Log message + logger.info("Error moving the coverage file into the BAM folder {} to {}", bwPath, targetPath, e); } - if (targetPath.toFile().exists()) { + if (moveSuccessful) { bwPath = targetPath; - logger.info("Coverage file was copied into the BAM folder: {}", bwPath); + logger.info("Coverage file was moved into the BAM folder: {}", bwPath); } else { - logger.info("Couldn't copy the coverage file into the BAM folder. The coverage file is in the job folder instead: {}", + logger.info("Couldn't move the coverage file into the BAM folder. The coverage file is in the job folder instead: {}", bwPath); } diff --git a/opencga-analysis/src/main/java/org/opencb/opencga/analysis/alignment/AlignmentIndexOperation.java b/opencga-analysis/src/main/java/org/opencb/opencga/analysis/alignment/AlignmentIndexOperation.java index 5aedd4f1162..a2b0fce9bec 100644 --- a/opencga-analysis/src/main/java/org/opencb/opencga/analysis/alignment/AlignmentIndexOperation.java +++ b/opencga-analysis/src/main/java/org/opencb/opencga/analysis/alignment/AlignmentIndexOperation.java @@ -85,20 +85,22 @@ protected void run() throws Exception { throw new ToolException("Something wrong happened when computing index file for '" + inputFile + "'"); } - // Try to copy the BAI file into the BAM file directory + // Try to move the BAI file into the BAM file directory + boolean moveSuccessful = false; Path targetPath = inputPath.getParent().resolve(outputPath.getFileName()); try { - Files.move(outputPath, targetPath); + Path movedPath = Files.move(outputPath, targetPath); + moveSuccessful = targetPath.equals(movedPath); } catch (Exception e) { - // Do nothing - logger.info("Moving from {} to {}: {}", outputPath, targetPath, e.getMessage()); + // Log message + logger.info("Error moving from {} to {}", outputPath, targetPath, e); } - if (targetPath.toFile().exists()) { + if (moveSuccessful) { outputPath = targetPath; - logger.info("Alignment index file was copied into the BAM folder: {}", outputPath); + logger.info("Alignment index file was moved into the BAM folder: {}", outputPath); } else { - logger.info("Couldn't copy the alignment index file into the BAM folder. The index file is in the job folder instead: {}", + logger.info("Couldn't move the alignment index file into the BAM folder. The index file is in the job folder instead: {}", outputPath); } From ed003a5cbf9e23e588d5d61b66c9f96dad3e2b44 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacobo=20Coll=20Morag=C3=B3n?= Date: Tue, 19 Mar 2024 16:47:22 +0000 Subject: [PATCH 07/85] storage: Do not use cellbase-client mixin converter. #TASK-5563 --- .../core/variant/io/json/mixin/ConsequenceTypeMixin.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/io/json/mixin/ConsequenceTypeMixin.java b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/io/json/mixin/ConsequenceTypeMixin.java index ad643f53068..ab4946fc572 100644 --- a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/io/json/mixin/ConsequenceTypeMixin.java +++ b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/io/json/mixin/ConsequenceTypeMixin.java @@ -4,12 +4,11 @@ import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.databind.util.StdConverter; import org.opencb.biodata.models.variant.avro.ConsequenceType; -import org.opencb.cellbase.client.rest.ParentRestClient; import java.util.List; @JsonDeserialize( - converter = ParentRestClient.ConsequenceTypeMixin.ConsequenceTypeConverter.class + converter = ConsequenceTypeMixin.ConsequenceTypeConverter.class ) public interface ConsequenceTypeMixin { class ConsequenceTypeConverter extends StdConverter { From a37f1b42a3ea0539a60e4162ea9a8dac287b57b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacobo=20Coll=20Morag=C3=B3n?= Date: Tue, 19 Mar 2024 17:16:04 +0000 Subject: [PATCH 08/85] storage: Accept non-normalized variants when filtering by ID or XREF. #TASK-5877 --- .../variant/query/VariantQueryParser.java | 26 +++++++++++++++++++ .../core/variant/query/VariantQueryUtils.java | 8 ++++++ .../VariantDBAdaptorMultiFileTest.java | 10 +++++++ .../adaptors/VariantDBAdaptorTest.java | 25 +++++++++++++----- .../sample/HBaseVariantSampleDataManager.java | 4 +-- 5 files changed, 65 insertions(+), 8 deletions(-) diff --git a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/VariantQueryParser.java b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/VariantQueryParser.java index 1564ad0fabf..6481d85c53c 100644 --- a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/VariantQueryParser.java +++ b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/VariantQueryParser.java @@ -8,7 +8,9 @@ import org.opencb.biodata.models.variant.Variant; import org.opencb.biodata.models.variant.avro.ClinicalSignificance; import org.opencb.biodata.models.variant.avro.VariantType; +import org.opencb.biodata.models.variant.exceptions.NonStandardCompliantSampleField; import org.opencb.biodata.models.variant.metadata.VariantFileHeaderComplexLine; +import org.opencb.biodata.tools.variant.VariantNormalizer; import org.opencb.commons.datastore.core.Query; import org.opencb.commons.datastore.core.QueryOptions; import org.opencb.commons.datastore.core.QueryParam; @@ -858,8 +860,17 @@ public static ParsedVariantQuery.VariantQueryXref parseXrefs(Query query) { } } } + } + if (!xrefs.getVariants().isEmpty()) { + List normalizedVariants = normalizeVariants(xrefs.getVariants()); + for (Variant normalizedVariant : normalizedVariants) { + if (!xrefs.getVariants().contains(normalizedVariant)) { + xrefs.getVariants().add(normalizedVariant); + } + } } + if (isValidParam(query, ANNOT_GENE_ROLE_IN_CANER_GENES)) { List thisGenes = query.getAsStringList(ANNOT_GENE_ROLE_IN_CANER_GENES.key()); if (thisGenes.size() != 1 || !thisGenes.get(0).equals(NONE)) { @@ -886,6 +897,21 @@ public static ParsedVariantQuery.VariantQueryXref parseXrefs(Query query) { return xrefs; } + public static Variant normalizeVariant(Variant variant) { + return normalizeVariants(Collections.singletonList(variant)).get(0); + } + + public static List normalizeVariants(List variants) { + VariantNormalizer variantNormalizer = new VariantNormalizer(); + List normalizedVariants; + try { + normalizedVariants = variantNormalizer.normalize(variants, false); + } catch (NonStandardCompliantSampleField e) { + throw VariantQueryException.internalException(e); + } + return normalizedVariants; + } + public static ParsedQuery> parseFreqFilter(Query query, QueryParam queryParam) { return VariantQueryUtils.splitValue(query, queryParam) .map(VariantQueryUtils::parseKeyOpValue) diff --git a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/VariantQueryUtils.java b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/VariantQueryUtils.java index 114379c77a9..75703f083d3 100644 --- a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/VariantQueryUtils.java +++ b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/VariantQueryUtils.java @@ -552,6 +552,14 @@ public static Variant toVariant(String value) { return variant; } + public static Variant toVariant(String variantStr, boolean normalize) { + Variant variant = toVariant(variantStr); + if (normalize && variant != null) { + return VariantQueryParser.normalizeVariant(variant); + } + return variant; + } + public static String[] splitStudyResource(String value) { int idx = value.lastIndexOf(STUDY_RESOURCE_SEPARATOR); if (idx <= 0 || idx == value.length() - 1) { diff --git a/opencga-storage/opencga-storage-core/src/test/java/org/opencb/opencga/storage/core/variant/adaptors/VariantDBAdaptorMultiFileTest.java b/opencga-storage/opencga-storage-core/src/test/java/org/opencb/opencga/storage/core/variant/adaptors/VariantDBAdaptorMultiFileTest.java index 9a95ed053e5..8ad47c67c2c 100644 --- a/opencga-storage/opencga-storage-core/src/test/java/org/opencb/opencga/storage/core/variant/adaptors/VariantDBAdaptorMultiFileTest.java +++ b/opencga-storage/opencga-storage-core/src/test/java/org/opencb/opencga/storage/core/variant/adaptors/VariantDBAdaptorMultiFileTest.java @@ -1333,6 +1333,16 @@ public void testSampleData() throws Exception { assertEquals(0, variant.getStudies().get(0).getFiles().size()); } + @Test + public void testSampleDataUnnormalized() throws Exception { + // Check unnormalized queries + Variant variant = variantStorageEngine.getSampleData("1:10352:T:TA", study1, new QueryOptions()).first(); + assertEquals("1:10353:-:A", variant.toString()); + System.out.println("variant = " + variant.toJson()); + assertNotNull(variant.getStudies().get(0).getStats(DEFAULT_COHORT)); + assertEquals(4, variant.getStudies().get(0).getSamples().size()); + assertEquals(4, variant.getStudies().get(0).getFiles().size()); + } @Test public void testCount() throws StorageEngineException { diff --git a/opencga-storage/opencga-storage-core/src/test/java/org/opencb/opencga/storage/core/variant/adaptors/VariantDBAdaptorTest.java b/opencga-storage/opencga-storage-core/src/test/java/org/opencb/opencga/storage/core/variant/adaptors/VariantDBAdaptorTest.java index 1f305574a64..b5bd4b841c3 100644 --- a/opencga-storage/opencga-storage-core/src/test/java/org/opencb/opencga/storage/core/variant/adaptors/VariantDBAdaptorTest.java +++ b/opencga-storage/opencga-storage-core/src/test/java/org/opencb/opencga/storage/core/variant/adaptors/VariantDBAdaptorTest.java @@ -30,9 +30,7 @@ import org.opencb.biodata.models.variant.Variant; import org.opencb.biodata.models.variant.VariantFileMetadata; import org.opencb.biodata.models.variant.avro.*; -import org.opencb.biodata.models.variant.exceptions.NonStandardCompliantSampleField; import org.opencb.biodata.models.variant.stats.VariantStats; -import org.opencb.biodata.tools.variant.VariantNormalizer; import org.opencb.commons.datastore.core.DataResult; import org.opencb.commons.datastore.core.ObjectMap; import org.opencb.commons.datastore.core.Query; @@ -531,11 +529,14 @@ public long filterPopulation(DataResult queryResult, Predicate public void testGetAllVariants_variantId() { int i = 0; List variants = new ArrayList<>(); + Map normalizedVariants = new HashMap<>(); for (Variant variant : allVariants.getResults()) { - if (i++ % 10 == 0) { - if (!variant.isSymbolic()) { - variants.add(variant); - } + if ((i++ % 10) == 0) { + variants.add(variant); + } + OriginalCall call = variant.getStudies().get(0).getFiles().get(0).getCall(); + if (call != null) { + normalizedVariants.put(variant.toString(), call.getVariantId()); } } List result = query(new Query(ID.key(), variants), new QueryOptions()).getResults(); @@ -554,6 +555,18 @@ public void testGetAllVariants_variantId() { } } assertEquals(expectedList, actualList); + + normalizedVariants.forEach((key, value) -> { + System.out.println(key + " = " + value); + }); + List resultNormalized = query(new Query(ID.key(), normalizedVariants.values()).append(INCLUDE_FILE.key(), ALL), new QueryOptions()).getResults(); + assertEquals(normalizedVariants.size(), resultNormalized.size()); + assertTrue(!resultNormalized.isEmpty()); + for (Variant variant : resultNormalized) { + String expected = normalizedVariants.get(variant.toString()); + String actual = variant.getStudies().get(0).getFiles().get(0).getCall().getVariantId(); + assertEquals(expected, actual); + } } @Test diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/adaptors/sample/HBaseVariantSampleDataManager.java b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/adaptors/sample/HBaseVariantSampleDataManager.java index 588833cfb6e..cbe7e0880c2 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/adaptors/sample/HBaseVariantSampleDataManager.java +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/adaptors/sample/HBaseVariantSampleDataManager.java @@ -26,8 +26,8 @@ import org.opencb.opencga.storage.hadoop.variant.GenomeHelper; import org.opencb.opencga.storage.hadoop.variant.adaptors.VariantHadoopDBAdaptor; import org.opencb.opencga.storage.hadoop.variant.adaptors.phoenix.PhoenixHelper; -import org.opencb.opencga.storage.hadoop.variant.adaptors.phoenix.VariantPhoenixSchema; import org.opencb.opencga.storage.hadoop.variant.adaptors.phoenix.VariantPhoenixKeyFactory; +import org.opencb.opencga.storage.hadoop.variant.adaptors.phoenix.VariantPhoenixSchema; import org.opencb.opencga.storage.hadoop.variant.converters.HBaseVariantConverterConfiguration; import org.opencb.opencga.storage.hadoop.variant.converters.VariantRow; import org.opencb.opencga.storage.hadoop.variant.converters.annotation.HBaseToVariantAnnotationConverter; @@ -64,7 +64,7 @@ protected DataResult getSampleData(String variantStr, String study, Que final Variant variant; if (VariantQueryUtils.isVariantId(variantStr)) { - variant = new Variant(variantStr); + variant = VariantQueryUtils.toVariant(variantStr, true); } else { variant = cellBaseUtils.getVariant(variantStr); } From 16d0a626478bf54f0f5eee347868a08f8a481ebb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacobo=20Coll=20Morag=C3=B3n?= Date: Wed, 20 Mar 2024 08:37:33 +0000 Subject: [PATCH 09/85] storage: Do return invalid cohort stats #TASK-5876 --- .../core/metadata/VariantStorageMetadataManager.java | 5 +++++ .../query/projection/VariantQueryProjectionParser.java | 7 +------ .../adaptors/phoenix/VariantPhoenixSchemaManager.java | 2 +- .../hadoop/variant/analysis/julie/JulieToolDriver.java | 1 + .../search/SecondaryIndexPendingVariantsDescriptor.java | 2 +- 5 files changed, 9 insertions(+), 8 deletions(-) diff --git a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/metadata/VariantStorageMetadataManager.java b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/metadata/VariantStorageMetadataManager.java index cf4477bb4f1..ce037e948dc 100644 --- a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/metadata/VariantStorageMetadataManager.java +++ b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/metadata/VariantStorageMetadataManager.java @@ -1135,6 +1135,11 @@ public Iterable getInvalidCohorts(int studyId) { return () -> Iterators.filter(cohortIterator(studyId), CohortMetadata::isInvalid); } + public Iterable getCalculatedOrInvalidCohorts(int studyId) { + return () -> Iterators.filter(cohortIterator(studyId), + cohortMetadata -> cohortMetadata.isStatsReady() || cohortMetadata.isInvalid()); + } + public CohortMetadata setSamplesToCohort(int studyId, String cohortName, Collection samples) throws StorageEngineException { return updateCohortSamples(studyId, cohortName, samples, false); } diff --git a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/projection/VariantQueryProjectionParser.java b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/projection/VariantQueryProjectionParser.java index 371903a7626..0860aa87a4d 100644 --- a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/projection/VariantQueryProjectionParser.java +++ b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/projection/VariantQueryProjectionParser.java @@ -125,14 +125,9 @@ public VariantQueryProjection parseVariantQueryProjection(Query query, QueryOpti for (VariantQueryProjection.StudyVariantQueryProjection study : studies.values()) { int studyId = study.getId(); List cohorts = new LinkedList<>(); - for (CohortMetadata cohort : metadataManager.getCalculatedCohorts(studyId)) { + for (CohortMetadata cohort : metadataManager.getCalculatedOrInvalidCohorts(studyId)) { cohorts.add(cohort.getId()); } -// metadataManager.cohortIterator(studyId).forEachRemaining(cohort -> { -// if (cohort.isReady()/* || cohort.isInvalid()*/) { -// cohorts.add(cohort.getId()); -// } -// }); study.setCohorts(cohorts); } } diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/adaptors/phoenix/VariantPhoenixSchemaManager.java b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/adaptors/phoenix/VariantPhoenixSchemaManager.java index 2d1d4c59e04..4ffa3c7aa55 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/adaptors/phoenix/VariantPhoenixSchemaManager.java +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/adaptors/phoenix/VariantPhoenixSchemaManager.java @@ -79,7 +79,7 @@ public void registerStudyColumns(int studyId) throws StorageEngineException { registerNewFiles(studyId, new ArrayList<>(metadataManager.getIndexedFiles(studyId))); List cohortIds = new LinkedList<>(); - for (CohortMetadata cohort : metadataManager.getCalculatedCohorts(studyId)) { + for (CohortMetadata cohort : metadataManager.getCalculatedOrInvalidCohorts(studyId)) { cohortIds.add(cohort.getId()); } registerNewCohorts(studyId, cohortIds); diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/analysis/julie/JulieToolDriver.java b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/analysis/julie/JulieToolDriver.java index 2321e25f6e1..4442bf48927 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/analysis/julie/JulieToolDriver.java +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/analysis/julie/JulieToolDriver.java @@ -68,6 +68,7 @@ protected void parseAndValidateParameters() throws IOException { for (Integer studyId : metadataManager.getStudies().values()) { List studyCohorts = new LinkedList<>(); cohorts.put(studyId, studyCohorts); + // Only READY cohort stats are used for JulieTool for (CohortMetadata c : metadataManager.getCalculatedCohorts(studyId)) { studyCohorts.add(c.getId()); } diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/search/SecondaryIndexPendingVariantsDescriptor.java b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/search/SecondaryIndexPendingVariantsDescriptor.java index 59c55cf8dda..604611ca93c 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/search/SecondaryIndexPendingVariantsDescriptor.java +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/search/SecondaryIndexPendingVariantsDescriptor.java @@ -61,7 +61,7 @@ public Scan configureScan(Scan scan, VariantStorageMetadataManager metadataManag scan.addColumn(GenomeHelper.COLUMN_FAMILY_BYTES, INDEX_STUDIES.bytes()); for (Integer studyId : metadataManager.getStudyIds()) { scan.addColumn(GenomeHelper.COLUMN_FAMILY_BYTES, VariantPhoenixSchema.getStudyColumn(studyId).bytes()); - for (CohortMetadata cohort : metadataManager.getCalculatedCohorts(studyId)) { + for (CohortMetadata cohort : metadataManager.getCalculatedOrInvalidCohorts(studyId)) { scan.addColumn(GenomeHelper.COLUMN_FAMILY_BYTES, VariantPhoenixSchema.getStatsColumn(studyId, cohort.getId()).bytes()); } } From 57fbbe1f77e8e21a3bcc41ed2e7bab26f5971c77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joaqu=C3=ADn=20T=C3=A1rraga=20Gim=C3=A9nez?= Date: Mon, 25 Mar 2024 09:37:48 +0100 Subject: [PATCH 10/85] tests: add Junit tests, #TASK-5858 --- .../alignment/AlignmentIndexOperation.java | 44 ++--- .../alignment/AlignmentStorageManager.java | 31 ++-- .../opencga/analysis/tools/OpenCgaTool.java | 3 + .../alignment/AlignmentAnalysisTest.java | 159 +++++++++++++++++- .../executors/AlignmentCommandExecutor.java | 8 +- .../options/AlignmentCommandOptions.java | 7 +- .../alignment/AlignmentIndexParams.java | 16 +- 7 files changed, 208 insertions(+), 60 deletions(-) diff --git a/opencga-analysis/src/main/java/org/opencb/opencga/analysis/alignment/AlignmentIndexOperation.java b/opencga-analysis/src/main/java/org/opencb/opencga/analysis/alignment/AlignmentIndexOperation.java index a2b0fce9bec..6f9fdf7bce7 100644 --- a/opencga-analysis/src/main/java/org/opencb/opencga/analysis/alignment/AlignmentIndexOperation.java +++ b/opencga-analysis/src/main/java/org/opencb/opencga/analysis/alignment/AlignmentIndexOperation.java @@ -19,26 +19,30 @@ import org.opencb.biodata.tools.alignment.BamManager; import org.opencb.commons.datastore.core.QueryOptions; import org.opencb.opencga.analysis.tools.OpenCgaTool; +import org.opencb.opencga.analysis.tools.OpenCgaToolScopeStudy; import org.opencb.opencga.catalog.exceptions.CatalogException; import org.opencb.opencga.core.exceptions.ToolException; +import org.opencb.opencga.core.models.alignment.AlignmentIndexParams; +import org.opencb.opencga.core.models.alignment.CoverageIndexParams; import org.opencb.opencga.core.models.common.Enums; import org.opencb.opencga.core.models.common.InternalStatus; import org.opencb.opencga.core.models.file.*; import org.opencb.opencga.core.response.OpenCGAResult; import org.opencb.opencga.core.tools.annotations.Tool; +import org.opencb.opencga.core.tools.annotations.ToolParams; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; @Tool(id = AlignmentIndexOperation.ID, resource = Enums.Resource.ALIGNMENT, description = "Index alignment.") -public class AlignmentIndexOperation extends OpenCgaTool { +public class AlignmentIndexOperation extends OpenCgaToolScopeStudy { public static final String ID = "alignment-index-run"; public static final String DESCRIPTION = "Index a given alignment file, e.g., create a .bai file from a .bam file"; - private String study; - private String inputFile; + @ToolParams + protected final AlignmentIndexParams indexParams = new AlignmentIndexParams(); private File inputCatalogFile; private Path inputPath; @@ -50,12 +54,12 @@ protected void check() throws Exception { OpenCGAResult fileResult; try { - fileResult = catalogManager.getFileManager().get(getStudy(), inputFile, QueryOptions.empty(), token); + fileResult = catalogManager.getFileManager().get(getStudy(), indexParams.getFileId(), QueryOptions.empty(), token); } catch (CatalogException e) { - throw new ToolException("Error accessing file '" + inputFile + "' of the study " + study + "'", e); + throw new ToolException("Error accessing file '" + indexParams.getFileId() + "' of the study " + study + "'", e); } if (fileResult.getNumResults() <= 0) { - throw new ToolException("File '" + inputFile + "' not found in study '" + study + "'"); + throw new ToolException("File '" + indexParams.getFileId() + "' not found in study '" + study + "'"); } inputCatalogFile = fileResult.getResults().get(0); @@ -64,7 +68,7 @@ protected void check() throws Exception { // Check if the input file is .bam or .cram if (!filename.endsWith(AlignmentConstants.BAM_EXTENSION) && !filename.endsWith(AlignmentConstants.CRAM_EXTENSION)) { - throw new ToolException("Invalid input alignment file '" + inputFile + "': it must be in BAM or CRAM format"); + throw new ToolException("Invalid input alignment file '" + indexParams.getFileId() + "': it must be in BAM or CRAM format"); } outputPath = getOutDir().resolve(filename + (filename.endsWith(AlignmentConstants.BAM_EXTENSION) @@ -73,6 +77,9 @@ protected void check() throws Exception { @Override protected void run() throws Exception { + setUpStorageEngineExecutor(study); + + logger.info("Running with parameters {}", indexParams); step(ID, () -> { // Compute index if necessary @@ -82,7 +89,7 @@ protected void run() throws Exception { bamManager.close(); if (!outputPath.toFile().exists()) { - throw new ToolException("Something wrong happened when computing index file for '" + inputFile + "'"); + throw new ToolException("Something wrong happened when computing index file for '" + indexParams.getFileId() + "'"); } // Try to move the BAI file into the BAM file directory @@ -105,7 +112,8 @@ protected void run() throws Exception { } // Link generated BAI file and update samples info, related file - File baiCatalogFile = AlignmentAnalysisUtils.linkAndUpdate(inputCatalogFile, outputPath, getJobId(), study, catalogManager, token); + File baiCatalogFile = AlignmentAnalysisUtils.linkAndUpdate(inputCatalogFile, outputPath, getJobId(), study, catalogManager, + token); // Update BAM file internal in order to set the alignment index (BAI) FileInternalAlignmentIndex fileAlignmentIndex = new FileInternalAlignmentIndex(new InternalStatus(InternalStatus.READY), @@ -113,22 +121,4 @@ protected void run() throws Exception { catalogManager.getFileManager().updateFileInternalAlignmentIndex(inputCatalogFile, fileAlignmentIndex, token); }); } - - public String getStudy() { - return study; - } - - public AlignmentIndexOperation setStudy(String study) { - this.study = study; - return this; - } - - public String getInputFile() { - return inputFile; - } - - public AlignmentIndexOperation setInputFile(String inputFile) { - this.inputFile = inputFile; - return this; - } } diff --git a/opencga-analysis/src/main/java/org/opencb/opencga/analysis/alignment/AlignmentStorageManager.java b/opencga-analysis/src/main/java/org/opencb/opencga/analysis/alignment/AlignmentStorageManager.java index 2aa314a9fd5..5c267add689 100644 --- a/opencga-analysis/src/main/java/org/opencb/opencga/analysis/alignment/AlignmentStorageManager.java +++ b/opencga-analysis/src/main/java/org/opencb/opencga/analysis/alignment/AlignmentStorageManager.java @@ -34,12 +34,16 @@ import org.opencb.opencga.analysis.StorageManager; import org.opencb.opencga.analysis.models.FileInfo; import org.opencb.opencga.analysis.models.StudyInfo; +import org.opencb.opencga.analysis.tools.ToolRunner; import org.opencb.opencga.catalog.db.api.FileDBAdaptor; import org.opencb.opencga.catalog.db.api.ProjectDBAdaptor; import org.opencb.opencga.catalog.exceptions.CatalogException; import org.opencb.opencga.catalog.managers.CatalogManager; import org.opencb.opencga.catalog.utils.ParamUtils; +import org.opencb.opencga.core.api.ParamConstants; import org.opencb.opencga.core.exceptions.ToolException; +import org.opencb.opencga.core.models.alignment.AlignmentIndexParams; +import org.opencb.opencga.core.models.alignment.CoverageIndexParams; import org.opencb.opencga.core.models.file.File; import org.opencb.opencga.core.models.project.Project; import org.opencb.opencga.core.models.study.Study; @@ -87,21 +91,18 @@ public AlignmentStorageManager(CatalogManager catalogManager, StorageEngineFacto initStatsMap(); } - //------------------------------------------------------------------------- - // INDEX - //------------------------------------------------------------------------- - - public void index(String study, String inputFile, String outdir, String token) throws ToolException { - ObjectMap params = new ObjectMap(); - - AlignmentIndexOperation indexOperation = new AlignmentIndexOperation(); - indexOperation.setUp(null, catalogManager, storageEngineFactory, params, Paths.get(outdir), jobId, token); - - indexOperation.setStudy(study); - indexOperation.setInputFile(inputFile); - - indexOperation.start(); - } +// //------------------------------------------------------------------------- +// // INDEX +// //------------------------------------------------------------------------- +// +// public void index(String study, String inputFile, String outdir, String token) throws ToolException { +// ToolRunner toolRunner = new ToolRunner("", catalogManager, storageEngineFactory); +// +// AlignmentIndexParams params = new AlignmentIndexParams(); +// params.setFileId(inputFile); +// toolRunner.execute(AlignmentIndexOperation.class, params, new ObjectMap(ParamConstants.STUDY_PARAM, study), Paths.get(outdir), +// jobId, token); +// } //------------------------------------------------------------------------- // QUERY diff --git a/opencga-analysis/src/main/java/org/opencb/opencga/analysis/tools/OpenCgaTool.java b/opencga-analysis/src/main/java/org/opencb/opencga/analysis/tools/OpenCgaTool.java index 7769315137b..835a0c92259 100644 --- a/opencga-analysis/src/main/java/org/opencb/opencga/analysis/tools/OpenCgaTool.java +++ b/opencga-analysis/src/main/java/org/opencb/opencga/analysis/tools/OpenCgaTool.java @@ -317,6 +317,9 @@ private void privateCheck() throws Exception { * @throws Exception if the parameters are not correct */ protected void check() throws Exception { + if (StringUtils.isEmpty(jobId)) { + throw new IllegalArgumentException("Missing job ID"); + } } /** diff --git a/opencga-analysis/src/test/java/org/opencb/opencga/analysis/alignment/AlignmentAnalysisTest.java b/opencga-analysis/src/test/java/org/opencb/opencga/analysis/alignment/AlignmentAnalysisTest.java index 71af17f701e..8964c2bf603 100644 --- a/opencga-analysis/src/test/java/org/opencb/opencga/analysis/alignment/AlignmentAnalysisTest.java +++ b/opencga-analysis/src/test/java/org/opencb/opencga/analysis/alignment/AlignmentAnalysisTest.java @@ -16,10 +16,7 @@ package org.opencb.opencga.analysis.alignment; -import org.junit.AfterClass; -import org.junit.Before; -import org.junit.ClassRule; -import org.junit.Test; +import org.junit.*; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; @@ -37,8 +34,11 @@ import org.opencb.opencga.core.config.storage.StorageConfiguration; import org.opencb.opencga.core.exceptions.ToolException; import org.opencb.opencga.core.models.alignment.AlignmentGeneCoverageStatsParams; +import org.opencb.opencga.core.models.alignment.AlignmentIndexParams; +import org.opencb.opencga.core.models.alignment.CoverageIndexParams; import org.opencb.opencga.core.models.file.File; import org.opencb.opencga.core.models.file.FileLinkParams; +import org.opencb.opencga.core.models.file.FileRelatedFile; import org.opencb.opencga.core.models.user.Account; import org.opencb.opencga.core.testclassification.duration.MediumTests; import org.opencb.opencga.storage.core.StorageEngineFactory; @@ -47,9 +47,11 @@ import org.opencb.opencga.storage.hadoop.variant.HadoopVariantStorageTest; import java.io.IOException; +import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.Arrays; +import java.util.Collections; import java.util.Map; import static org.junit.Assert.assertEquals; @@ -252,7 +254,6 @@ public void setUpCatalogManager() throws IOException, CatalogException { // assertEquals(2, individual.getSamples().size()); } - @Test public void geneCoverageStatsTest() throws IOException, ToolException, CatalogException { Path outdir = Paths.get(opencga.createTmpOutdir("_genecoveragestats")); @@ -270,7 +271,7 @@ public void geneCoverageStatsTest() throws IOException, ToolException, CatalogEx String geneName = "BRCA2"; params.setGenes(Arrays.asList(geneName)); - toolRunner.execute(AlignmentGeneCoverageStatsAnalysis.class, params, new ObjectMap(), outdir, null, token); + toolRunner.execute(AlignmentGeneCoverageStatsAnalysis.class, params, new ObjectMap(), outdir, "coverage-job-id", token); bamFile = catalogManager.getFileManager().link(STUDY, new FileLinkParams(bamFilename, "", "", "", null, null, null, null, null), false, token).first(); @@ -278,4 +279,150 @@ public void geneCoverageStatsTest() throws IOException, ToolException, CatalogEx assertEquals(geneName, bamFile.getQualityControl().getCoverage().getGeneCoverageStats().get(0).getGeneName()); assertEquals(10, bamFile.getQualityControl().getCoverage().getGeneCoverageStats().get(0).getStats().size()); } + + @Test + public void testNonReadOnlyAlignmentIndex() throws Exception { + Path nonReadOnlyDir = Paths.get(opencga.createTmpOutdir("_non_readonly_alignment_index")); + Path bamPath = Paths.get(opencga.getResourceUri("biofiles/HG00096.chrom20.small.bam").getPath()); + String bamFilename = "NonReadOnlyAligmentIndex_" + bamPath.getFileName(); + Files.copy(bamPath, nonReadOnlyDir.resolve(bamFilename)); + + File bamFile = catalogManager.getFileManager().link(STUDY, new FileLinkParams(nonReadOnlyDir.resolve(bamFilename).toAbsolutePath().toString(), "non_readonly_alignment_index", "", "", null, null, null, + null, null), true, token).first(); + + // Run alignment index + AlignmentIndexParams params = new AlignmentIndexParams(); + params.setFileId(bamFile.getId()); + Path alignmentIndexOutdir = Paths.get(opencga.createTmpOutdir("_alignment_index")); + toolRunner.execute(AlignmentIndexOperation.class, params, new ObjectMap(ParamConstants.STUDY_PARAM, STUDY), alignmentIndexOutdir, "jobId-non-readonly-coverage-index", token); + + // Checking BAI file + Path baiPath = nonReadOnlyDir.resolve(bamFilename + AlignmentConstants.BAI_EXTENSION); + Assert.assertTrue(Files.exists(baiPath)); + + // Checking BAI file is registered in the BAM file internals + File baiFile = catalogManager.getFileManager().get(STUDY, Collections.singletonList(bamFilename + AlignmentConstants.BAI_EXTENSION), QueryOptions.empty(), true, token).first(); + bamFile = catalogManager.getFileManager().get(STUDY, Collections.singletonList(bamFile.getId()), QueryOptions.empty(), true, token).first(); + Assert.assertEquals(baiFile.getId(), bamFile.getInternal().getAlignment().getIndex().getFileId()); + } + + @Test + public void testReadOnlyAlignmentIndex() throws Exception { + Path readOnlyDir = Paths.get(opencga.createTmpOutdir("_readonly_for_alignment_index")); + Path bamPath = Paths.get(opencga.getResourceUri("biofiles/HG00096.chrom20.small.bam").getPath()); + String bamFilename = "ReadOnlyAligmentIndex_" + bamPath.getFileName(); + Files.copy(bamPath, readOnlyDir.resolve(bamFilename)); + + // Make read-only + Runtime.getRuntime().exec("chmod 555 " + readOnlyDir.toAbsolutePath()); + + File bamFile = catalogManager.getFileManager().link(STUDY, new FileLinkParams(readOnlyDir.resolve(bamFilename).toAbsolutePath().toString(), "readonly_alignment_index", "", "", null, null, null, + null, null), true, token).first(); + + // Run alignment index + AlignmentIndexParams params = new AlignmentIndexParams(); + params.setFileId(bamFile.getId()); + Path alignmentIndexOutdir = Paths.get(opencga.createTmpOutdir("_alignment_index")); + toolRunner.execute(AlignmentIndexOperation.class, params, new ObjectMap(ParamConstants.STUDY_PARAM, STUDY), alignmentIndexOutdir, "jobId-readonly-coverage-index", token); + + // Checking BAI file + Path baiPath = alignmentIndexOutdir.resolve(bamFilename + AlignmentConstants.BAI_EXTENSION); + Assert.assertTrue(Files.exists(baiPath)); + + // Checking BAI file is registered in the BAM file internals + File baiFile = catalogManager.getFileManager().get(STUDY, Collections.singletonList(bamFilename + AlignmentConstants.BAI_EXTENSION), QueryOptions.empty(), true, token).first(); + bamFile = catalogManager.getFileManager().get(STUDY, Collections.singletonList(bamFile.getId()), QueryOptions.empty(), true, token).first(); + Assert.assertEquals(baiFile.getId(), bamFile.getInternal().getAlignment().getIndex().getFileId()); + + Runtime.getRuntime().exec("chmod 777 " + readOnlyDir.toAbsolutePath()); + } + + @Test + public void testNonReadOnlyCoverageIndex() throws Exception { + Path nonReadOnlyDir = Paths.get(opencga.createTmpOutdir("_non_readonly_for_coverage_index")); + Path bamPath = Paths.get(opencga.getResourceUri("biofiles/HG00096.chrom20.small.bam").getPath()); + String bamFilename = "NonReadOnlyCoverageIndex_" + bamPath.getFileName(); + Files.copy(bamPath, nonReadOnlyDir.resolve(bamFilename)); + + File bamFile = catalogManager.getFileManager().link(STUDY, new FileLinkParams(nonReadOnlyDir.resolve(bamFilename).toAbsolutePath().toString(), "non_readonly_alignment_coverage_index", "", "", null, null, null, + null, null), true, token).first(); + + // Run alignment index + AlignmentIndexParams indexParams = new AlignmentIndexParams(); + indexParams.setFileId(bamFile.getId()); + Path alignmentIndexOutdir = Paths.get(opencga.createTmpOutdir("_alignment_index")); + toolRunner.execute(AlignmentIndexOperation.class, indexParams, new ObjectMap(ParamConstants.STUDY_PARAM, STUDY), alignmentIndexOutdir, "jobId-non-readonly-alignment-coverage-index", token); + + // Checking BAI file + Path baiPath = nonReadOnlyDir.resolve(bamFilename + AlignmentConstants.BAI_EXTENSION); + Assert.assertTrue(Files.exists(baiPath)); + + // Checking BAI file is registered in the BAM file internals + File baiFile = catalogManager.getFileManager().get(STUDY, Collections.singletonList(bamFilename + AlignmentConstants.BAI_EXTENSION), QueryOptions.empty(), true, token).first(); + bamFile = catalogManager.getFileManager().get(STUDY, Collections.singletonList(bamFile.getId()), QueryOptions.empty(), true, token).first(); + Assert.assertEquals(baiFile.getId(), bamFile.getInternal().getAlignment().getIndex().getFileId()); + + // Run coverage index + CoverageIndexParams coverageOarams = new CoverageIndexParams(); + coverageOarams.setBamFileId(bamFile.getId()); + coverageOarams.setBaiFileId(baiFile.getId()); + Path coverageIndexOutdir = Paths.get(opencga.createTmpOutdir("_coverage_index")); + toolRunner.execute(AlignmentCoverageAnalysis.class, coverageOarams, new ObjectMap(ParamConstants.STUDY_PARAM, STUDY), coverageIndexOutdir, "jobId-readonly-coverage-index", token); + + // Checking BW file + Path bwPath = nonReadOnlyDir.resolve(bamFilename + AlignmentConstants.BIGWIG_EXTENSION); + Assert.assertTrue(Files.exists(bwPath)); + + // Checking BAM file is registered in the related files of BW file + File bwFile = catalogManager.getFileManager().get(STUDY, Collections.singletonList(bwPath.getFileName().toString()), QueryOptions.empty(), true, token).first(); + Assert.assertEquals(bamFile.getId(), bwFile.getRelatedFiles().get(0).getFile().getId()); + Assert.assertEquals(FileRelatedFile.Relation.ALIGNMENT, bwFile.getRelatedFiles().get(0).getRelation()); + } + + @Test + public void testReadOnlyCoverageIndex() throws Exception { + Path readOnlyDir = Paths.get(opencga.createTmpOutdir("_readonly_for_coverage_index")); + Path bamPath = Paths.get(opencga.getResourceUri("biofiles/HG00096.chrom20.small.bam").getPath()); + String bamFilename = "ReadOnlyCoverageIndex_" + bamPath.getFileName(); + Files.copy(bamPath, readOnlyDir.resolve(bamFilename)); + + File bamFile = catalogManager.getFileManager().link(STUDY, new FileLinkParams(readOnlyDir.resolve(bamFilename).toAbsolutePath().toString(), "readonly_alignment_coverage_index", "", "", null, null, null, + null, null), true, token).first(); + + // Run alignment index + AlignmentIndexParams indexParams = new AlignmentIndexParams(); + indexParams.setFileId(bamFile.getId()); + Path alignmentIndexOutdir = Paths.get(opencga.createTmpOutdir("_alignment_index")); + toolRunner.execute(AlignmentIndexOperation.class, indexParams, new ObjectMap(ParamConstants.STUDY_PARAM, STUDY), alignmentIndexOutdir, "jobId-readonly-coverage-index", token); + + // Checking BAI file + Path baiPath = readOnlyDir.resolve(bamFilename + AlignmentConstants.BAI_EXTENSION); + Assert.assertTrue(Files.exists(baiPath)); + + // Checking BAI file is registered in the BAM file internals + File baiFile = catalogManager.getFileManager().get(STUDY, Collections.singletonList(bamFilename + AlignmentConstants.BAI_EXTENSION), QueryOptions.empty(), true, token).first(); + bamFile = catalogManager.getFileManager().get(STUDY, Collections.singletonList(bamFile.getId()), QueryOptions.empty(), true, token).first(); + Assert.assertEquals(baiFile.getId(), bamFile.getInternal().getAlignment().getIndex().getFileId()); + + // Make read-only + Runtime.getRuntime().exec("chmod 555 " + readOnlyDir.toAbsolutePath()); + + // Run coverage index + CoverageIndexParams coverageOarams = new CoverageIndexParams(); + coverageOarams.setBamFileId(bamFile.getId()); + coverageOarams.setBaiFileId(baiFile.getId()); + Path coverageIndexOutdir = Paths.get(opencga.createTmpOutdir("_coverage_index")); + toolRunner.execute(AlignmentCoverageAnalysis.class, coverageOarams, new ObjectMap(ParamConstants.STUDY_PARAM, STUDY), coverageIndexOutdir, "jobId-readonly-coverage-index", token); + + // Checking BW file + Path bwPath = coverageIndexOutdir.resolve(bamFilename + AlignmentConstants.BIGWIG_EXTENSION); + Assert.assertTrue(Files.exists(bwPath)); + + // Checking BAM file is registered in the related files of BW file + File bwFile = catalogManager.getFileManager().get(STUDY, Collections.singletonList(bwPath.getFileName().toString()), QueryOptions.empty(), true, token).first(); + Assert.assertEquals(bamFile.getId(), bwFile.getRelatedFiles().get(0).getFile().getId()); + Assert.assertEquals(FileRelatedFile.Relation.ALIGNMENT, bwFile.getRelatedFiles().get(0).getRelation()); + + Runtime.getRuntime().exec("chmod 777 " + readOnlyDir.toAbsolutePath()); + } } \ No newline at end of file diff --git a/opencga-app/src/main/java/org/opencb/opencga/app/cli/internal/executors/AlignmentCommandExecutor.java b/opencga-app/src/main/java/org/opencb/opencga/app/cli/internal/executors/AlignmentCommandExecutor.java index 07ed1b36c1f..436fff7b061 100644 --- a/opencga-app/src/main/java/org/opencb/opencga/app/cli/internal/executors/AlignmentCommandExecutor.java +++ b/opencga-app/src/main/java/org/opencb/opencga/app/cli/internal/executors/AlignmentCommandExecutor.java @@ -18,6 +18,7 @@ import org.opencb.commons.datastore.core.ObjectMap; import org.opencb.opencga.analysis.alignment.AlignmentCoverageAnalysis; +import org.opencb.opencga.analysis.alignment.AlignmentIndexOperation; import org.opencb.opencga.analysis.alignment.AlignmentStorageManager; import org.opencb.opencga.analysis.alignment.qc.AlignmentGeneCoverageStatsAnalysis; import org.opencb.opencga.analysis.alignment.qc.AlignmentQcAnalysis; @@ -119,9 +120,12 @@ public void execute() throws Exception { private void indexRun() throws Exception { AlignmentCommandOptions.IndexAlignmentCommandOptions cliOptions = alignmentCommandOptions.indexAlignmentCommandOptions; - AlignmentStorageManager alignmentManager = new AlignmentStorageManager(catalogManager, storageEngineFactory, alignmentCommandOptions.internalJobOptions.jobId); + ObjectMap params = new AlignmentIndexParams( + cliOptions.fileId, + cliOptions.overwrite + ).toObjectMap(cliOptions.commonOptions.params).append(ParamConstants.STUDY_PARAM, cliOptions.study); - alignmentManager.index(cliOptions.study, cliOptions.file, cliOptions.outdir, cliOptions.commonOptions.token); + toolRunner.execute(AlignmentIndexOperation.class, params, Paths.get(cliOptions.outdir), jobId, token); } diff --git a/opencga-app/src/main/java/org/opencb/opencga/app/cli/internal/options/AlignmentCommandOptions.java b/opencga-app/src/main/java/org/opencb/opencga/app/cli/internal/options/AlignmentCommandOptions.java index 628988b9302..3834c5ee4c5 100644 --- a/opencga-app/src/main/java/org/opencb/opencga/app/cli/internal/options/AlignmentCommandOptions.java +++ b/opencga-app/src/main/java/org/opencb/opencga/app/cli/internal/options/AlignmentCommandOptions.java @@ -104,8 +104,11 @@ public class IndexAlignmentCommandOptions extends GeneralCliOptions.StudyOption @ParametersDelegate public Object internalJobOptions = internalJobOptionsObject; - @Parameter(names = {"--file"}, description = FILE_ID_DESCRIPTION, required = true, arity = 1) - public String file; + @Parameter(names = {"--file-id"}, description = FILE_ID_DESCRIPTION, required = true, arity = 1) + public String fileId; + + @Parameter(names = {"--overwrite"}, description = "Force to overwrite the alignment index file", arity = 0) + public boolean overwrite; @Parameter(names = {"-o", "--outdir"}, description = OUTPUT_DIRECTORY_DESCRIPTION) public String outdir; diff --git a/opencga-core/src/main/java/org/opencb/opencga/core/models/alignment/AlignmentIndexParams.java b/opencga-core/src/main/java/org/opencb/opencga/core/models/alignment/AlignmentIndexParams.java index b4e4dc87607..741d089c2f0 100644 --- a/opencga-core/src/main/java/org/opencb/opencga/core/models/alignment/AlignmentIndexParams.java +++ b/opencga-core/src/main/java/org/opencb/opencga/core/models/alignment/AlignmentIndexParams.java @@ -5,32 +5,32 @@ public class AlignmentIndexParams extends ToolParams { public static final String DESCRIPTION = "Alignment index params"; - private String file; + private String fileId; private boolean overwrite; public AlignmentIndexParams() { } - public AlignmentIndexParams(String file, boolean overwrite) { - this.file = file; + public AlignmentIndexParams(String fileId, boolean overwrite) { + this.fileId = fileId; this.overwrite = overwrite; } @Override public String toString() { final StringBuilder sb = new StringBuilder("AlignmentIndexParams{"); - sb.append("file='").append(file).append('\''); + sb.append("fileId='").append(fileId).append('\''); sb.append(", overwrite=").append(overwrite); sb.append('}'); return sb.toString(); } - public String getFile() { - return file; + public String getFileId() { + return fileId; } - public AlignmentIndexParams setFile(String file) { - this.file = file; + public AlignmentIndexParams setFileId(String fileId) { + this.fileId = fileId; return this; } From c550fd3c1810b1c160e3e9ef44037d555edb4c07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joaqu=C3=ADn=20T=C3=A1rraga=20Gim=C3=A9nez?= Date: Mon, 25 Mar 2024 10:25:26 +0100 Subject: [PATCH 11/85] client: generate clients, #TASK-5858 --- .../app/cli/main/OpenCgaCompleter.java | 2 +- .../app/cli/main/OpencgaCliOptionsParser.java | 2 +- .../AnalysisAlignmentCommandExecutor.java | 2 +- .../executors/SamplesCommandExecutor.java | 1 + .../AnalysisAlignmentCommandOptions.java | 14 ++++++------- opencga-client/src/main/R/R/Admin-methods.R | 2 +- .../src/main/R/R/Alignment-methods.R | 2 +- opencga-client/src/main/R/R/AllGenerics.R | 20 +++++++++---------- .../src/main/R/R/Clinical-methods.R | 4 ++-- opencga-client/src/main/R/R/Cohort-methods.R | 4 ++-- opencga-client/src/main/R/R/Family-methods.R | 4 ++-- opencga-client/src/main/R/R/File-methods.R | 4 ++-- opencga-client/src/main/R/R/GA4GH-methods.R | 4 ++-- .../src/main/R/R/Individual-methods.R | 4 ++-- opencga-client/src/main/R/R/Job-methods.R | 4 ++-- opencga-client/src/main/R/R/Meta-methods.R | 2 +- .../src/main/R/R/Operation-methods.R | 2 +- opencga-client/src/main/R/R/Panel-methods.R | 2 +- opencga-client/src/main/R/R/Project-methods.R | 2 +- opencga-client/src/main/R/R/Sample-methods.R | 4 ++-- opencga-client/src/main/R/R/Study-methods.R | 4 ++-- opencga-client/src/main/R/R/User-methods.R | 4 ++-- opencga-client/src/main/R/R/Variant-methods.R | 2 +- .../client/rest/clients/AdminClient.java | 4 ++-- .../client/rest/clients/AlignmentClient.java | 4 ++-- .../rest/clients/ClinicalAnalysisClient.java | 4 ++-- .../client/rest/clients/CohortClient.java | 4 ++-- .../rest/clients/DiseasePanelClient.java | 4 ++-- .../client/rest/clients/FamilyClient.java | 4 ++-- .../client/rest/clients/FileClient.java | 4 ++-- .../client/rest/clients/GA4GHClient.java | 4 ++-- .../client/rest/clients/IndividualClient.java | 4 ++-- .../client/rest/clients/JobClient.java | 4 ++-- .../client/rest/clients/MetaClient.java | 4 ++-- .../client/rest/clients/ProjectClient.java | 4 ++-- .../client/rest/clients/SampleClient.java | 4 ++-- .../client/rest/clients/StudyClient.java | 4 ++-- .../client/rest/clients/UserClient.java | 4 ++-- .../client/rest/clients/VariantClient.java | 4 ++-- .../rest/clients/VariantOperationClient.java | 4 ++-- opencga-client/src/main/javascript/Admin.js | 2 +- .../src/main/javascript/Alignment.js | 2 +- .../src/main/javascript/ClinicalAnalysis.js | 2 +- opencga-client/src/main/javascript/Cohort.js | 2 +- .../src/main/javascript/DiseasePanel.js | 2 +- opencga-client/src/main/javascript/Family.js | 2 +- opencga-client/src/main/javascript/File.js | 2 +- opencga-client/src/main/javascript/GA4GH.js | 2 +- .../src/main/javascript/Individual.js | 2 +- opencga-client/src/main/javascript/Job.js | 2 +- opencga-client/src/main/javascript/Meta.js | 2 +- opencga-client/src/main/javascript/Project.js | 2 +- opencga-client/src/main/javascript/Sample.js | 2 +- opencga-client/src/main/javascript/Study.js | 2 +- opencga-client/src/main/javascript/User.js | 2 +- opencga-client/src/main/javascript/Variant.js | 2 +- .../src/main/javascript/VariantOperation.js | 2 +- .../pyopencga/rest_clients/admin_client.py | 4 ++-- .../rest_clients/alignment_client.py | 4 ++-- .../rest_clients/clinical_analysis_client.py | 4 ++-- .../pyopencga/rest_clients/cohort_client.py | 4 ++-- .../rest_clients/disease_panel_client.py | 4 ++-- .../pyopencga/rest_clients/family_client.py | 4 ++-- .../pyopencga/rest_clients/file_client.py | 4 ++-- .../pyopencga/rest_clients/ga4gh_client.py | 4 ++-- .../rest_clients/individual_client.py | 4 ++-- .../pyopencga/rest_clients/job_client.py | 4 ++-- .../pyopencga/rest_clients/meta_client.py | 4 ++-- .../pyopencga/rest_clients/project_client.py | 4 ++-- .../pyopencga/rest_clients/sample_client.py | 4 ++-- .../pyopencga/rest_clients/study_client.py | 4 ++-- .../pyopencga/rest_clients/user_client.py | 4 ++-- .../pyopencga/rest_clients/variant_client.py | 4 ++-- .../rest_clients/variant_operation_client.py | 4 ++-- .../opencga/core/api/FieldConstants.java | 10 ++++++++++ .../alignment/AlignmentIndexParams.java | 5 +++++ .../models/alignment/CoverageIndexParams.java | 9 ++++++++- .../alignment/AlignmentStorageOptions.java | 4 ++-- 78 files changed, 158 insertions(+), 135 deletions(-) diff --git a/opencga-app/src/main/java/org/opencb/opencga/app/cli/main/OpenCgaCompleter.java b/opencga-app/src/main/java/org/opencb/opencga/app/cli/main/OpenCgaCompleter.java index 48db1bde2fd..bc6dce57f25 100644 --- a/opencga-app/src/main/java/org/opencb/opencga/app/cli/main/OpenCgaCompleter.java +++ b/opencga-app/src/main/java/org/opencb/opencga/app/cli/main/OpenCgaCompleter.java @@ -1,5 +1,5 @@ /* -* Copyright 2015-2024-02-14 OpenCB +* Copyright 2015-2024-03-25 OpenCB * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/opencga-app/src/main/java/org/opencb/opencga/app/cli/main/OpencgaCliOptionsParser.java b/opencga-app/src/main/java/org/opencb/opencga/app/cli/main/OpencgaCliOptionsParser.java index af1660a9e33..227a9a33a29 100644 --- a/opencga-app/src/main/java/org/opencb/opencga/app/cli/main/OpencgaCliOptionsParser.java +++ b/opencga-app/src/main/java/org/opencb/opencga/app/cli/main/OpencgaCliOptionsParser.java @@ -1,5 +1,5 @@ /* -* Copyright 2015-2024-02-14 OpenCB +* Copyright 2015-2024-03-25 OpenCB * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/opencga-app/src/main/java/org/opencb/opencga/app/cli/main/executors/AnalysisAlignmentCommandExecutor.java b/opencga-app/src/main/java/org/opencb/opencga/app/cli/main/executors/AnalysisAlignmentCommandExecutor.java index 217b7421f32..88c7345e9da 100644 --- a/opencga-app/src/main/java/org/opencb/opencga/app/cli/main/executors/AnalysisAlignmentCommandExecutor.java +++ b/opencga-app/src/main/java/org/opencb/opencga/app/cli/main/executors/AnalysisAlignmentCommandExecutor.java @@ -387,7 +387,7 @@ private RestResponse runIndex() throws Exception { .readValue(new java.io.File(commandOptions.jsonFile), AlignmentIndexParams.class); } else { ObjectMap beanParams = new ObjectMap(); - putNestedIfNotEmpty(beanParams, "file",commandOptions.file, true); + putNestedIfNotEmpty(beanParams, "fileId",commandOptions.fileId, true); putNestedIfNotNull(beanParams, "overwrite",commandOptions.overwrite, true); alignmentIndexParams = JacksonUtils.getDefaultObjectMapper().copy() diff --git a/opencga-app/src/main/java/org/opencb/opencga/app/cli/main/executors/SamplesCommandExecutor.java b/opencga-app/src/main/java/org/opencb/opencga/app/cli/main/executors/SamplesCommandExecutor.java index 7ed949a68a5..328cc9eb556 100644 --- a/opencga-app/src/main/java/org/opencb/opencga/app/cli/main/executors/SamplesCommandExecutor.java +++ b/opencga-app/src/main/java/org/opencb/opencga/app/cli/main/executors/SamplesCommandExecutor.java @@ -125,6 +125,7 @@ private RestResponse updateAcl() throws Exception { queryParams.putIfNotEmpty("study", sessionManager.getSession().getCurrentStudy()); } + SampleAclUpdateParams sampleAclUpdateParams = null; if (commandOptions.jsonDataModel) { RestResponse res = new RestResponse<>(); diff --git a/opencga-app/src/main/java/org/opencb/opencga/app/cli/main/options/AnalysisAlignmentCommandOptions.java b/opencga-app/src/main/java/org/opencb/opencga/app/cli/main/options/AnalysisAlignmentCommandOptions.java index cb5e4f77e45..004e650e9c1 100644 --- a/opencga-app/src/main/java/org/opencb/opencga/app/cli/main/options/AnalysisAlignmentCommandOptions.java +++ b/opencga-app/src/main/java/org/opencb/opencga/app/cli/main/options/AnalysisAlignmentCommandOptions.java @@ -142,14 +142,14 @@ public class RunCoverageIndexCommandOptions { @Parameter(names = {"--job-tags"}, description = "Job tags", required = false, arity = 1) public String jobTags; - @Parameter(names = {"--bam-file-id"}, description = "The body web service bamFileId parameter", required = false, arity = 1) + @Parameter(names = {"--bam-file-id"}, description = "BAM file ID.", required = false, arity = 1) public String bamFileId; - @Parameter(names = {"--bai-file-id"}, description = "The body web service baiFileId parameter", required = false, arity = 1) + @Parameter(names = {"--bai-file-id"}, description = "BAI file ID.", required = false, arity = 1) public String baiFileId; - @Parameter(names = {"--window-size"}, description = "The body web service windowSize parameter", required = false, arity = 1) - public Integer windowSize; + @Parameter(names = {"--window-size"}, description = "Window size (i.e., the size of the bins, in bases, for the output of the BIGWIG file).", required = false, arity = 1) + public Integer windowSize = 50; } @@ -387,10 +387,10 @@ public class RunIndexCommandOptions { @Parameter(names = {"--job-tags"}, description = "Job tags", required = false, arity = 1) public String jobTags; - @Parameter(names = {"--file"}, description = "The body web service file parameter", required = false, arity = 1) - public String file; + @Parameter(names = {"--file-id"}, description = "File ID, (i.e., BAM/CRAM file ID).", required = false, arity = 1) + public String fileId; - @Parameter(names = {"--overwrite"}, description = "The body web service overwrite parameter", required = false, help = true, arity = 0) + @Parameter(names = {"--overwrite"}, description = "Flag to force indexing.", required = false, help = true, arity = 0) public boolean overwrite = false; } diff --git a/opencga-client/src/main/R/R/Admin-methods.R b/opencga-client/src/main/R/R/Admin-methods.R index c3041969f51..6b3092bf980 100644 --- a/opencga-client/src/main/R/R/Admin-methods.R +++ b/opencga-client/src/main/R/R/Admin-methods.R @@ -2,7 +2,7 @@ # WARNING: AUTOGENERATED CODE # # This code was generated by a tool. -# Autogenerated on: 2024-02-14 +# Autogenerated on: 2024-03-25 # # Manual changes to this file may cause unexpected behavior in your application. # Manual changes to this file will be overwritten if the code is regenerated. diff --git a/opencga-client/src/main/R/R/Alignment-methods.R b/opencga-client/src/main/R/R/Alignment-methods.R index 53cd5d9802c..ff929629b43 100644 --- a/opencga-client/src/main/R/R/Alignment-methods.R +++ b/opencga-client/src/main/R/R/Alignment-methods.R @@ -2,7 +2,7 @@ # WARNING: AUTOGENERATED CODE # # This code was generated by a tool. -# Autogenerated on: 2024-02-14 +# Autogenerated on: 2024-03-25 # # Manual changes to this file may cause unexpected behavior in your application. # Manual changes to this file will be overwritten if the code is regenerated. diff --git a/opencga-client/src/main/R/R/AllGenerics.R b/opencga-client/src/main/R/R/AllGenerics.R index f9fdb51fe6f..c9fe9d1bedd 100644 --- a/opencga-client/src/main/R/R/AllGenerics.R +++ b/opencga-client/src/main/R/R/AllGenerics.R @@ -1,6 +1,6 @@ # ############################################################################## ## UserClient -setGeneric("userClient", function(OpencgaR, user, users, filterId, endpointName, params=NULL, ...) +setGeneric("userClient", function(OpencgaR, user, filterId, users, endpointName, params=NULL, ...) standardGeneric("userClient")) # ############################################################################## @@ -10,37 +10,37 @@ setGeneric("projectClient", function(OpencgaR, project, projects, endpointName, # ############################################################################## ## StudyClient -setGeneric("studyClient", function(OpencgaR, group, variableSet, studies, templateId, study, members, endpointName, params=NULL, ...) +setGeneric("studyClient", function(OpencgaR, study, templateId, group, variableSet, studies, members, endpointName, params=NULL, ...) standardGeneric("studyClient")) # ############################################################################## ## FileClient -setGeneric("fileClient", function(OpencgaR, folder, annotationSet, file, files, members, endpointName, params=NULL, ...) +setGeneric("fileClient", function(OpencgaR, file, files, members, annotationSet, folder, endpointName, params=NULL, ...) standardGeneric("fileClient")) # ############################################################################## ## JobClient -setGeneric("jobClient", function(OpencgaR, job, members, jobs, endpointName, params=NULL, ...) +setGeneric("jobClient", function(OpencgaR, jobs, job, members, endpointName, params=NULL, ...) standardGeneric("jobClient")) # ############################################################################## ## SampleClient -setGeneric("sampleClient", function(OpencgaR, samples, annotationSet, members, sample, endpointName, params=NULL, ...) +setGeneric("sampleClient", function(OpencgaR, sample, annotationSet, samples, members, endpointName, params=NULL, ...) standardGeneric("sampleClient")) # ############################################################################## ## IndividualClient -setGeneric("individualClient", function(OpencgaR, individuals, members, annotationSet, individual, endpointName, params=NULL, ...) +setGeneric("individualClient", function(OpencgaR, individual, annotationSet, individuals, members, endpointName, params=NULL, ...) standardGeneric("individualClient")) # ############################################################################## ## FamilyClient -setGeneric("familyClient", function(OpencgaR, families, family, members, annotationSet, endpointName, params=NULL, ...) +setGeneric("familyClient", function(OpencgaR, family, annotationSet, families, members, endpointName, params=NULL, ...) standardGeneric("familyClient")) # ############################################################################## ## CohortClient -setGeneric("cohortClient", function(OpencgaR, cohort, members, annotationSet, cohorts, endpointName, params=NULL, ...) +setGeneric("cohortClient", function(OpencgaR, cohorts, annotationSet, cohort, members, endpointName, params=NULL, ...) standardGeneric("cohortClient")) # ############################################################################## @@ -60,7 +60,7 @@ setGeneric("variantClient", function(OpencgaR, endpointName, params=NULL, ...) # ############################################################################## ## ClinicalClient -setGeneric("clinicalClient", function(OpencgaR, interpretation, clinicalAnalysis, interpretations, annotationSet, clinicalAnalyses, members, endpointName, params=NULL, ...) +setGeneric("clinicalClient", function(OpencgaR, interpretation, interpretations, members, annotationSet, clinicalAnalyses, clinicalAnalysis, endpointName, params=NULL, ...) standardGeneric("clinicalClient")) # ############################################################################## @@ -75,7 +75,7 @@ setGeneric("metaClient", function(OpencgaR, endpointName, params=NULL, ...) # ############################################################################## ## GA4GHClient -setGeneric("ga4ghClient", function(OpencgaR, study, file, endpointName, params=NULL, ...) +setGeneric("ga4ghClient", function(OpencgaR, file, study, endpointName, params=NULL, ...) standardGeneric("ga4ghClient")) # ############################################################################## diff --git a/opencga-client/src/main/R/R/Clinical-methods.R b/opencga-client/src/main/R/R/Clinical-methods.R index ecd04d6d74d..ab921c9a324 100644 --- a/opencga-client/src/main/R/R/Clinical-methods.R +++ b/opencga-client/src/main/R/R/Clinical-methods.R @@ -2,7 +2,7 @@ # WARNING: AUTOGENERATED CODE # # This code was generated by a tool. -# Autogenerated on: 2024-02-14 +# Autogenerated on: 2024-03-25 # # Manual changes to this file may cause unexpected behavior in your application. # Manual changes to this file will be overwritten if the code is regenerated. @@ -61,7 +61,7 @@ #' [*]: Required parameter #' @export -setMethod("clinicalClient", "OpencgaR", function(OpencgaR, interpretation, clinicalAnalysis, interpretations, annotationSet, clinicalAnalyses, members, endpointName, params=NULL, ...) { +setMethod("clinicalClient", "OpencgaR", function(OpencgaR, interpretation, interpretations, members, annotationSet, clinicalAnalyses, clinicalAnalysis, endpointName, params=NULL, ...) { switch(endpointName, #' @section Endpoint /{apiVersion}/analysis/clinical/acl/{members}/update: diff --git a/opencga-client/src/main/R/R/Cohort-methods.R b/opencga-client/src/main/R/R/Cohort-methods.R index b4cbb071860..1c8bfe6a9a4 100644 --- a/opencga-client/src/main/R/R/Cohort-methods.R +++ b/opencga-client/src/main/R/R/Cohort-methods.R @@ -2,7 +2,7 @@ # WARNING: AUTOGENERATED CODE # # This code was generated by a tool. -# Autogenerated on: 2024-02-14 +# Autogenerated on: 2024-03-25 # # Manual changes to this file may cause unexpected behavior in your application. # Manual changes to this file will be overwritten if the code is regenerated. @@ -39,7 +39,7 @@ #' [*]: Required parameter #' @export -setMethod("cohortClient", "OpencgaR", function(OpencgaR, cohort, members, annotationSet, cohorts, endpointName, params=NULL, ...) { +setMethod("cohortClient", "OpencgaR", function(OpencgaR, cohorts, annotationSet, cohort, members, endpointName, params=NULL, ...) { switch(endpointName, #' @section Endpoint /{apiVersion}/cohorts/acl/{members}/update: diff --git a/opencga-client/src/main/R/R/Family-methods.R b/opencga-client/src/main/R/R/Family-methods.R index 9f965314e0f..b6a81bd9d62 100644 --- a/opencga-client/src/main/R/R/Family-methods.R +++ b/opencga-client/src/main/R/R/Family-methods.R @@ -2,7 +2,7 @@ # WARNING: AUTOGENERATED CODE # # This code was generated by a tool. -# Autogenerated on: 2024-02-14 +# Autogenerated on: 2024-03-25 # # Manual changes to this file may cause unexpected behavior in your application. # Manual changes to this file will be overwritten if the code is regenerated. @@ -38,7 +38,7 @@ #' [*]: Required parameter #' @export -setMethod("familyClient", "OpencgaR", function(OpencgaR, families, family, members, annotationSet, endpointName, params=NULL, ...) { +setMethod("familyClient", "OpencgaR", function(OpencgaR, family, annotationSet, families, members, endpointName, params=NULL, ...) { switch(endpointName, #' @section Endpoint /{apiVersion}/families/acl/{members}/update: diff --git a/opencga-client/src/main/R/R/File-methods.R b/opencga-client/src/main/R/R/File-methods.R index fd0ad7f691c..05947f708e9 100644 --- a/opencga-client/src/main/R/R/File-methods.R +++ b/opencga-client/src/main/R/R/File-methods.R @@ -2,7 +2,7 @@ # WARNING: AUTOGENERATED CODE # # This code was generated by a tool. -# Autogenerated on: 2024-02-14 +# Autogenerated on: 2024-03-25 # # Manual changes to this file may cause unexpected behavior in your application. # Manual changes to this file will be overwritten if the code is regenerated. @@ -54,7 +54,7 @@ #' [*]: Required parameter #' @export -setMethod("fileClient", "OpencgaR", function(OpencgaR, folder, annotationSet, file, files, members, endpointName, params=NULL, ...) { +setMethod("fileClient", "OpencgaR", function(OpencgaR, file, files, members, annotationSet, folder, endpointName, params=NULL, ...) { switch(endpointName, #' @section Endpoint /{apiVersion}/files/acl/{members}/update: diff --git a/opencga-client/src/main/R/R/GA4GH-methods.R b/opencga-client/src/main/R/R/GA4GH-methods.R index d9d2c5689e4..a22a564ca30 100644 --- a/opencga-client/src/main/R/R/GA4GH-methods.R +++ b/opencga-client/src/main/R/R/GA4GH-methods.R @@ -2,7 +2,7 @@ # WARNING: AUTOGENERATED CODE # # This code was generated by a tool. -# Autogenerated on: 2024-02-14 +# Autogenerated on: 2024-03-25 # # Manual changes to this file may cause unexpected behavior in your application. # Manual changes to this file will be overwritten if the code is regenerated. @@ -31,7 +31,7 @@ #' [*]: Required parameter #' @export -setMethod("ga4ghClient", "OpencgaR", function(OpencgaR, study, file, endpointName, params=NULL, ...) { +setMethod("ga4ghClient", "OpencgaR", function(OpencgaR, file, study, endpointName, params=NULL, ...) { switch(endpointName, #' @section Endpoint /{apiVersion}/ga4gh/reads/search: diff --git a/opencga-client/src/main/R/R/Individual-methods.R b/opencga-client/src/main/R/R/Individual-methods.R index 72d5e0839dc..284a83342da 100644 --- a/opencga-client/src/main/R/R/Individual-methods.R +++ b/opencga-client/src/main/R/R/Individual-methods.R @@ -2,7 +2,7 @@ # WARNING: AUTOGENERATED CODE # # This code was generated by a tool. -# Autogenerated on: 2024-02-14 +# Autogenerated on: 2024-03-25 # # Manual changes to this file may cause unexpected behavior in your application. # Manual changes to this file will be overwritten if the code is regenerated. @@ -39,7 +39,7 @@ #' [*]: Required parameter #' @export -setMethod("individualClient", "OpencgaR", function(OpencgaR, individuals, members, annotationSet, individual, endpointName, params=NULL, ...) { +setMethod("individualClient", "OpencgaR", function(OpencgaR, individual, annotationSet, individuals, members, endpointName, params=NULL, ...) { switch(endpointName, #' @section Endpoint /{apiVersion}/individuals/acl/{members}/update: diff --git a/opencga-client/src/main/R/R/Job-methods.R b/opencga-client/src/main/R/R/Job-methods.R index edfb52fbaff..df7dd2e0b4a 100644 --- a/opencga-client/src/main/R/R/Job-methods.R +++ b/opencga-client/src/main/R/R/Job-methods.R @@ -2,7 +2,7 @@ # WARNING: AUTOGENERATED CODE # # This code was generated by a tool. -# Autogenerated on: 2024-02-14 +# Autogenerated on: 2024-03-25 # # Manual changes to this file may cause unexpected behavior in your application. # Manual changes to this file will be overwritten if the code is regenerated. @@ -40,7 +40,7 @@ #' [*]: Required parameter #' @export -setMethod("jobClient", "OpencgaR", function(OpencgaR, job, members, jobs, endpointName, params=NULL, ...) { +setMethod("jobClient", "OpencgaR", function(OpencgaR, jobs, job, members, endpointName, params=NULL, ...) { switch(endpointName, #' @section Endpoint /{apiVersion}/jobs/acl/{members}/update: diff --git a/opencga-client/src/main/R/R/Meta-methods.R b/opencga-client/src/main/R/R/Meta-methods.R index 730500d7b4a..74bf2d9681b 100644 --- a/opencga-client/src/main/R/R/Meta-methods.R +++ b/opencga-client/src/main/R/R/Meta-methods.R @@ -2,7 +2,7 @@ # WARNING: AUTOGENERATED CODE # # This code was generated by a tool. -# Autogenerated on: 2024-02-14 +# Autogenerated on: 2024-03-25 # # Manual changes to this file may cause unexpected behavior in your application. # Manual changes to this file will be overwritten if the code is regenerated. diff --git a/opencga-client/src/main/R/R/Operation-methods.R b/opencga-client/src/main/R/R/Operation-methods.R index 11e89656de2..272fae083ea 100644 --- a/opencga-client/src/main/R/R/Operation-methods.R +++ b/opencga-client/src/main/R/R/Operation-methods.R @@ -2,7 +2,7 @@ # WARNING: AUTOGENERATED CODE # # This code was generated by a tool. -# Autogenerated on: 2024-02-14 +# Autogenerated on: 2024-03-25 # # Manual changes to this file may cause unexpected behavior in your application. # Manual changes to this file will be overwritten if the code is regenerated. diff --git a/opencga-client/src/main/R/R/Panel-methods.R b/opencga-client/src/main/R/R/Panel-methods.R index 3d1c5bfb8d3..59ee1588d55 100644 --- a/opencga-client/src/main/R/R/Panel-methods.R +++ b/opencga-client/src/main/R/R/Panel-methods.R @@ -2,7 +2,7 @@ # WARNING: AUTOGENERATED CODE # # This code was generated by a tool. -# Autogenerated on: 2024-02-14 +# Autogenerated on: 2024-03-25 # # Manual changes to this file may cause unexpected behavior in your application. # Manual changes to this file will be overwritten if the code is regenerated. diff --git a/opencga-client/src/main/R/R/Project-methods.R b/opencga-client/src/main/R/R/Project-methods.R index ebbcb80dd92..1f2f6982a13 100644 --- a/opencga-client/src/main/R/R/Project-methods.R +++ b/opencga-client/src/main/R/R/Project-methods.R @@ -2,7 +2,7 @@ # WARNING: AUTOGENERATED CODE # # This code was generated by a tool. -# Autogenerated on: 2024-02-14 +# Autogenerated on: 2024-03-25 # # Manual changes to this file may cause unexpected behavior in your application. # Manual changes to this file will be overwritten if the code is regenerated. diff --git a/opencga-client/src/main/R/R/Sample-methods.R b/opencga-client/src/main/R/R/Sample-methods.R index c5f0bbd3357..f6280a3164a 100644 --- a/opencga-client/src/main/R/R/Sample-methods.R +++ b/opencga-client/src/main/R/R/Sample-methods.R @@ -2,7 +2,7 @@ # WARNING: AUTOGENERATED CODE # # This code was generated by a tool. -# Autogenerated on: 2024-02-14 +# Autogenerated on: 2024-03-25 # # Manual changes to this file may cause unexpected behavior in your application. # Manual changes to this file will be overwritten if the code is regenerated. @@ -39,7 +39,7 @@ #' [*]: Required parameter #' @export -setMethod("sampleClient", "OpencgaR", function(OpencgaR, samples, annotationSet, members, sample, endpointName, params=NULL, ...) { +setMethod("sampleClient", "OpencgaR", function(OpencgaR, sample, annotationSet, samples, members, endpointName, params=NULL, ...) { switch(endpointName, #' @section Endpoint /{apiVersion}/samples/acl/{members}/update: diff --git a/opencga-client/src/main/R/R/Study-methods.R b/opencga-client/src/main/R/R/Study-methods.R index c86c0da79b1..a6e51aefaac 100644 --- a/opencga-client/src/main/R/R/Study-methods.R +++ b/opencga-client/src/main/R/R/Study-methods.R @@ -2,7 +2,7 @@ # WARNING: AUTOGENERATED CODE # # This code was generated by a tool. -# Autogenerated on: 2024-02-14 +# Autogenerated on: 2024-03-25 # # Manual changes to this file may cause unexpected behavior in your application. # Manual changes to this file will be overwritten if the code is regenerated. @@ -46,7 +46,7 @@ #' [*]: Required parameter #' @export -setMethod("studyClient", "OpencgaR", function(OpencgaR, group, variableSet, studies, templateId, study, members, endpointName, params=NULL, ...) { +setMethod("studyClient", "OpencgaR", function(OpencgaR, study, templateId, group, variableSet, studies, members, endpointName, params=NULL, ...) { switch(endpointName, #' @section Endpoint /{apiVersion}/studies/acl/{members}/update: diff --git a/opencga-client/src/main/R/R/User-methods.R b/opencga-client/src/main/R/R/User-methods.R index fb403c674e6..9624cdaf318 100644 --- a/opencga-client/src/main/R/R/User-methods.R +++ b/opencga-client/src/main/R/R/User-methods.R @@ -2,7 +2,7 @@ # WARNING: AUTOGENERATED CODE # # This code was generated by a tool. -# Autogenerated on: 2024-02-14 +# Autogenerated on: 2024-03-25 # # Manual changes to this file may cause unexpected behavior in your application. # Manual changes to this file will be overwritten if the code is regenerated. @@ -38,7 +38,7 @@ #' [*]: Required parameter #' @export -setMethod("userClient", "OpencgaR", function(OpencgaR, user, users, filterId, endpointName, params=NULL, ...) { +setMethod("userClient", "OpencgaR", function(OpencgaR, user, filterId, users, endpointName, params=NULL, ...) { switch(endpointName, #' @section Endpoint /{apiVersion}/users/login: diff --git a/opencga-client/src/main/R/R/Variant-methods.R b/opencga-client/src/main/R/R/Variant-methods.R index d114e5d4882..e03ee6ad6c8 100644 --- a/opencga-client/src/main/R/R/Variant-methods.R +++ b/opencga-client/src/main/R/R/Variant-methods.R @@ -2,7 +2,7 @@ # WARNING: AUTOGENERATED CODE # # This code was generated by a tool. -# Autogenerated on: 2024-02-14 +# Autogenerated on: 2024-03-25 # # Manual changes to this file may cause unexpected behavior in your application. # Manual changes to this file will be overwritten if the code is regenerated. diff --git a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/AdminClient.java b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/AdminClient.java index d4fcd4b1d60..8e30b07702a 100644 --- a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/AdminClient.java +++ b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/AdminClient.java @@ -36,7 +36,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. -* Autogenerated on: 2024-02-14 +* Autogenerated on: 2024-03-25 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. @@ -45,7 +45,7 @@ /** * This class contains methods for the Admin webservices. - * Client version: 2.12.3-SNAPSHOT + * Client version: 2.12.4-SNAPSHOT * PATH: admin */ public class AdminClient extends AbstractParentClient { diff --git a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/AlignmentClient.java b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/AlignmentClient.java index c6c8c84fd8b..57d98513e2c 100644 --- a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/AlignmentClient.java +++ b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/AlignmentClient.java @@ -40,7 +40,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. -* Autogenerated on: 2024-02-14 +* Autogenerated on: 2024-03-25 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. @@ -49,7 +49,7 @@ /** * This class contains methods for the Alignment webservices. - * Client version: 2.12.3-SNAPSHOT + * Client version: 2.12.4-SNAPSHOT * PATH: analysis/alignment */ public class AlignmentClient extends AbstractParentClient { diff --git a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/ClinicalAnalysisClient.java b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/ClinicalAnalysisClient.java index e4858049e0b..914bdf265e6 100644 --- a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/ClinicalAnalysisClient.java +++ b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/ClinicalAnalysisClient.java @@ -54,7 +54,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. -* Autogenerated on: 2024-02-14 +* Autogenerated on: 2024-03-25 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. @@ -63,7 +63,7 @@ /** * This class contains methods for the ClinicalAnalysis webservices. - * Client version: 2.12.3-SNAPSHOT + * Client version: 2.12.4-SNAPSHOT * PATH: analysis/clinical */ public class ClinicalAnalysisClient extends AbstractParentClient { diff --git a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/CohortClient.java b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/CohortClient.java index f136be11310..1226e56b605 100644 --- a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/CohortClient.java +++ b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/CohortClient.java @@ -37,7 +37,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. -* Autogenerated on: 2024-02-14 +* Autogenerated on: 2024-03-25 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. @@ -46,7 +46,7 @@ /** * This class contains methods for the Cohort webservices. - * Client version: 2.12.3-SNAPSHOT + * Client version: 2.12.4-SNAPSHOT * PATH: cohorts */ public class CohortClient extends AbstractParentClient { diff --git a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/DiseasePanelClient.java b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/DiseasePanelClient.java index 497e02f5445..52484158482 100644 --- a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/DiseasePanelClient.java +++ b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/DiseasePanelClient.java @@ -35,7 +35,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. -* Autogenerated on: 2024-02-14 +* Autogenerated on: 2024-03-25 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. @@ -44,7 +44,7 @@ /** * This class contains methods for the DiseasePanel webservices. - * Client version: 2.12.3-SNAPSHOT + * Client version: 2.12.4-SNAPSHOT * PATH: panels */ public class DiseasePanelClient extends AbstractParentClient { diff --git a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/FamilyClient.java b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/FamilyClient.java index 437d6e65255..2c1bb8f333f 100644 --- a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/FamilyClient.java +++ b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/FamilyClient.java @@ -36,7 +36,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. -* Autogenerated on: 2024-02-14 +* Autogenerated on: 2024-03-25 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. @@ -45,7 +45,7 @@ /** * This class contains methods for the Family webservices. - * Client version: 2.12.3-SNAPSHOT + * Client version: 2.12.4-SNAPSHOT * PATH: families */ public class FamilyClient extends AbstractParentClient { diff --git a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/FileClient.java b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/FileClient.java index 66ae008ab7c..255466ab18d 100644 --- a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/FileClient.java +++ b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/FileClient.java @@ -43,7 +43,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. -* Autogenerated on: 2024-02-14 +* Autogenerated on: 2024-03-25 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. @@ -52,7 +52,7 @@ /** * This class contains methods for the File webservices. - * Client version: 2.12.3-SNAPSHOT + * Client version: 2.12.4-SNAPSHOT * PATH: files */ public class FileClient extends AbstractParentClient { diff --git a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/GA4GHClient.java b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/GA4GHClient.java index 5d007b409bd..8f0d7ee9ac8 100644 --- a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/GA4GHClient.java +++ b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/GA4GHClient.java @@ -27,7 +27,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. -* Autogenerated on: 2024-02-14 +* Autogenerated on: 2024-03-25 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. @@ -36,7 +36,7 @@ /** * This class contains methods for the GA4GH webservices. - * Client version: 2.12.3-SNAPSHOT + * Client version: 2.12.4-SNAPSHOT * PATH: ga4gh */ public class GA4GHClient extends AbstractParentClient { diff --git a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/IndividualClient.java b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/IndividualClient.java index 67bb7feb715..0ca1523076b 100644 --- a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/IndividualClient.java +++ b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/IndividualClient.java @@ -36,7 +36,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. -* Autogenerated on: 2024-02-14 +* Autogenerated on: 2024-03-25 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. @@ -45,7 +45,7 @@ /** * This class contains methods for the Individual webservices. - * Client version: 2.12.3-SNAPSHOT + * Client version: 2.12.4-SNAPSHOT * PATH: individuals */ public class IndividualClient extends AbstractParentClient { diff --git a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/JobClient.java b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/JobClient.java index c4fb407be93..15e72d8b9c2 100644 --- a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/JobClient.java +++ b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/JobClient.java @@ -37,7 +37,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. -* Autogenerated on: 2024-02-14 +* Autogenerated on: 2024-03-25 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. @@ -46,7 +46,7 @@ /** * This class contains methods for the Job webservices. - * Client version: 2.12.3-SNAPSHOT + * Client version: 2.12.4-SNAPSHOT * PATH: jobs */ public class JobClient extends AbstractParentClient { diff --git a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/MetaClient.java b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/MetaClient.java index 4f1873c571c..b51239eb2fd 100644 --- a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/MetaClient.java +++ b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/MetaClient.java @@ -28,7 +28,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. -* Autogenerated on: 2024-02-14 +* Autogenerated on: 2024-03-25 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. @@ -37,7 +37,7 @@ /** * This class contains methods for the Meta webservices. - * Client version: 2.12.3-SNAPSHOT + * Client version: 2.12.4-SNAPSHOT * PATH: meta */ public class MetaClient extends AbstractParentClient { diff --git a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/ProjectClient.java b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/ProjectClient.java index 19b3144a06d..af4a142fa29 100644 --- a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/ProjectClient.java +++ b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/ProjectClient.java @@ -32,7 +32,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. -* Autogenerated on: 2024-02-14 +* Autogenerated on: 2024-03-25 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. @@ -41,7 +41,7 @@ /** * This class contains methods for the Project webservices. - * Client version: 2.12.3-SNAPSHOT + * Client version: 2.12.4-SNAPSHOT * PATH: projects */ public class ProjectClient extends AbstractParentClient { diff --git a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/SampleClient.java b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/SampleClient.java index f1e5b7ac798..92f3b0a7b8e 100644 --- a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/SampleClient.java +++ b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/SampleClient.java @@ -36,7 +36,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. -* Autogenerated on: 2024-02-14 +* Autogenerated on: 2024-03-25 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. @@ -45,7 +45,7 @@ /** * This class contains methods for the Sample webservices. - * Client version: 2.12.3-SNAPSHOT + * Client version: 2.12.4-SNAPSHOT * PATH: samples */ public class SampleClient extends AbstractParentClient { diff --git a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/StudyClient.java b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/StudyClient.java index 4a9b4550de8..567bba43ac0 100644 --- a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/StudyClient.java +++ b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/StudyClient.java @@ -45,7 +45,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. -* Autogenerated on: 2024-02-14 +* Autogenerated on: 2024-03-25 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. @@ -54,7 +54,7 @@ /** * This class contains methods for the Study webservices. - * Client version: 2.12.3-SNAPSHOT + * Client version: 2.12.4-SNAPSHOT * PATH: studies */ public class StudyClient extends AbstractParentClient { diff --git a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/UserClient.java b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/UserClient.java index bbf582a2cc6..ba89f64c209 100644 --- a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/UserClient.java +++ b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/UserClient.java @@ -36,7 +36,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. -* Autogenerated on: 2024-02-14 +* Autogenerated on: 2024-03-25 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. @@ -45,7 +45,7 @@ /** * This class contains methods for the User webservices. - * Client version: 2.12.3-SNAPSHOT + * Client version: 2.12.4-SNAPSHOT * PATH: users */ public class UserClient extends AbstractParentClient { diff --git a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/VariantClient.java b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/VariantClient.java index c7f91a4730a..8cba06e41f1 100644 --- a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/VariantClient.java +++ b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/VariantClient.java @@ -62,7 +62,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. -* Autogenerated on: 2024-02-14 +* Autogenerated on: 2024-03-25 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. @@ -71,7 +71,7 @@ /** * This class contains methods for the Variant webservices. - * Client version: 2.12.3-SNAPSHOT + * Client version: 2.12.4-SNAPSHOT * PATH: analysis/variant */ public class VariantClient extends AbstractParentClient { diff --git a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/VariantOperationClient.java b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/VariantOperationClient.java index 92f5dd6772d..4be682e046c 100644 --- a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/VariantOperationClient.java +++ b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/VariantOperationClient.java @@ -50,7 +50,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. -* Autogenerated on: 2024-02-14 +* Autogenerated on: 2024-03-25 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. @@ -59,7 +59,7 @@ /** * This class contains methods for the VariantOperation webservices. - * Client version: 2.12.3-SNAPSHOT + * Client version: 2.12.4-SNAPSHOT * PATH: operation */ public class VariantOperationClient extends AbstractParentClient { diff --git a/opencga-client/src/main/javascript/Admin.js b/opencga-client/src/main/javascript/Admin.js index 30fe2d2b09b..6aa2ba750f0 100644 --- a/opencga-client/src/main/javascript/Admin.js +++ b/opencga-client/src/main/javascript/Admin.js @@ -12,7 +12,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. - * Autogenerated on: 2024-02-14 + * Autogenerated on: 2024-03-25 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. diff --git a/opencga-client/src/main/javascript/Alignment.js b/opencga-client/src/main/javascript/Alignment.js index 764a51d164d..4be235b9baa 100644 --- a/opencga-client/src/main/javascript/Alignment.js +++ b/opencga-client/src/main/javascript/Alignment.js @@ -12,7 +12,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. - * Autogenerated on: 2024-02-14 + * Autogenerated on: 2024-03-25 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. diff --git a/opencga-client/src/main/javascript/ClinicalAnalysis.js b/opencga-client/src/main/javascript/ClinicalAnalysis.js index 1556652d3d3..51b323a39fe 100644 --- a/opencga-client/src/main/javascript/ClinicalAnalysis.js +++ b/opencga-client/src/main/javascript/ClinicalAnalysis.js @@ -12,7 +12,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. - * Autogenerated on: 2024-02-14 + * Autogenerated on: 2024-03-25 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. diff --git a/opencga-client/src/main/javascript/Cohort.js b/opencga-client/src/main/javascript/Cohort.js index 97ef19dcbdf..d39e5ae3b0c 100644 --- a/opencga-client/src/main/javascript/Cohort.js +++ b/opencga-client/src/main/javascript/Cohort.js @@ -12,7 +12,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. - * Autogenerated on: 2024-02-14 + * Autogenerated on: 2024-03-25 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. diff --git a/opencga-client/src/main/javascript/DiseasePanel.js b/opencga-client/src/main/javascript/DiseasePanel.js index 52601203a30..c87f942b1ef 100644 --- a/opencga-client/src/main/javascript/DiseasePanel.js +++ b/opencga-client/src/main/javascript/DiseasePanel.js @@ -12,7 +12,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. - * Autogenerated on: 2024-02-14 + * Autogenerated on: 2024-03-25 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. diff --git a/opencga-client/src/main/javascript/Family.js b/opencga-client/src/main/javascript/Family.js index 608c23c087d..be8254f473e 100644 --- a/opencga-client/src/main/javascript/Family.js +++ b/opencga-client/src/main/javascript/Family.js @@ -12,7 +12,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. - * Autogenerated on: 2024-02-14 + * Autogenerated on: 2024-03-25 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. diff --git a/opencga-client/src/main/javascript/File.js b/opencga-client/src/main/javascript/File.js index f09d5c4562f..ff20b03147f 100644 --- a/opencga-client/src/main/javascript/File.js +++ b/opencga-client/src/main/javascript/File.js @@ -12,7 +12,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. - * Autogenerated on: 2024-02-14 + * Autogenerated on: 2024-03-25 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. diff --git a/opencga-client/src/main/javascript/GA4GH.js b/opencga-client/src/main/javascript/GA4GH.js index b656c0bd696..4c77f6aeee8 100644 --- a/opencga-client/src/main/javascript/GA4GH.js +++ b/opencga-client/src/main/javascript/GA4GH.js @@ -12,7 +12,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. - * Autogenerated on: 2024-02-14 + * Autogenerated on: 2024-03-25 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. diff --git a/opencga-client/src/main/javascript/Individual.js b/opencga-client/src/main/javascript/Individual.js index d8bd896ae88..a6c6c726d37 100644 --- a/opencga-client/src/main/javascript/Individual.js +++ b/opencga-client/src/main/javascript/Individual.js @@ -12,7 +12,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. - * Autogenerated on: 2024-02-14 + * Autogenerated on: 2024-03-25 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. diff --git a/opencga-client/src/main/javascript/Job.js b/opencga-client/src/main/javascript/Job.js index 9489c82bc7a..57511d22c7f 100644 --- a/opencga-client/src/main/javascript/Job.js +++ b/opencga-client/src/main/javascript/Job.js @@ -12,7 +12,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. - * Autogenerated on: 2024-02-14 + * Autogenerated on: 2024-03-25 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. diff --git a/opencga-client/src/main/javascript/Meta.js b/opencga-client/src/main/javascript/Meta.js index b5636ff6a5e..a1fb0c9c5e5 100644 --- a/opencga-client/src/main/javascript/Meta.js +++ b/opencga-client/src/main/javascript/Meta.js @@ -12,7 +12,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. - * Autogenerated on: 2024-02-14 + * Autogenerated on: 2024-03-25 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. diff --git a/opencga-client/src/main/javascript/Project.js b/opencga-client/src/main/javascript/Project.js index bde7382c84d..60e5da7c399 100644 --- a/opencga-client/src/main/javascript/Project.js +++ b/opencga-client/src/main/javascript/Project.js @@ -12,7 +12,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. - * Autogenerated on: 2024-02-14 + * Autogenerated on: 2024-03-25 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. diff --git a/opencga-client/src/main/javascript/Sample.js b/opencga-client/src/main/javascript/Sample.js index 990f3b3b04e..e966c53483a 100644 --- a/opencga-client/src/main/javascript/Sample.js +++ b/opencga-client/src/main/javascript/Sample.js @@ -12,7 +12,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. - * Autogenerated on: 2024-02-14 + * Autogenerated on: 2024-03-25 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. diff --git a/opencga-client/src/main/javascript/Study.js b/opencga-client/src/main/javascript/Study.js index 7d443653ad9..1adcc948b35 100644 --- a/opencga-client/src/main/javascript/Study.js +++ b/opencga-client/src/main/javascript/Study.js @@ -12,7 +12,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. - * Autogenerated on: 2024-02-14 + * Autogenerated on: 2024-03-25 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. diff --git a/opencga-client/src/main/javascript/User.js b/opencga-client/src/main/javascript/User.js index 2093a3aadb4..09198885d55 100644 --- a/opencga-client/src/main/javascript/User.js +++ b/opencga-client/src/main/javascript/User.js @@ -12,7 +12,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. - * Autogenerated on: 2024-02-14 + * Autogenerated on: 2024-03-25 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. diff --git a/opencga-client/src/main/javascript/Variant.js b/opencga-client/src/main/javascript/Variant.js index c98bccd6bf5..c23df5f611e 100644 --- a/opencga-client/src/main/javascript/Variant.js +++ b/opencga-client/src/main/javascript/Variant.js @@ -12,7 +12,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. - * Autogenerated on: 2024-02-14 + * Autogenerated on: 2024-03-25 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. diff --git a/opencga-client/src/main/javascript/VariantOperation.js b/opencga-client/src/main/javascript/VariantOperation.js index ad54d4104cf..dcb04858c6c 100644 --- a/opencga-client/src/main/javascript/VariantOperation.js +++ b/opencga-client/src/main/javascript/VariantOperation.js @@ -12,7 +12,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. - * Autogenerated on: 2024-02-14 + * Autogenerated on: 2024-03-25 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. diff --git a/opencga-client/src/main/python/pyopencga/rest_clients/admin_client.py b/opencga-client/src/main/python/pyopencga/rest_clients/admin_client.py index 4a60e9c7e2f..8ed47fe0116 100644 --- a/opencga-client/src/main/python/pyopencga/rest_clients/admin_client.py +++ b/opencga-client/src/main/python/pyopencga/rest_clients/admin_client.py @@ -2,7 +2,7 @@ WARNING: AUTOGENERATED CODE This code was generated by a tool. - Autogenerated on: 2024-02-14 + Autogenerated on: 2024-03-25 Manual changes to this file may cause unexpected behavior in your application. Manual changes to this file will be overwritten if the code is regenerated. @@ -14,7 +14,7 @@ class Admin(_ParentRestClient): """ This class contains methods for the 'Admin' webservices - Client version: 2.12.3-SNAPSHOT + Client version: 2.12.4-SNAPSHOT PATH: /{apiVersion}/admin """ diff --git a/opencga-client/src/main/python/pyopencga/rest_clients/alignment_client.py b/opencga-client/src/main/python/pyopencga/rest_clients/alignment_client.py index 98b40a3f711..03ef44694c6 100644 --- a/opencga-client/src/main/python/pyopencga/rest_clients/alignment_client.py +++ b/opencga-client/src/main/python/pyopencga/rest_clients/alignment_client.py @@ -2,7 +2,7 @@ WARNING: AUTOGENERATED CODE This code was generated by a tool. - Autogenerated on: 2024-02-14 + Autogenerated on: 2024-03-25 Manual changes to this file may cause unexpected behavior in your application. Manual changes to this file will be overwritten if the code is regenerated. @@ -14,7 +14,7 @@ class Alignment(_ParentRestClient): """ This class contains methods for the 'Analysis - Alignment' webservices - Client version: 2.12.3-SNAPSHOT + Client version: 2.12.4-SNAPSHOT PATH: /{apiVersion}/analysis/alignment """ diff --git a/opencga-client/src/main/python/pyopencga/rest_clients/clinical_analysis_client.py b/opencga-client/src/main/python/pyopencga/rest_clients/clinical_analysis_client.py index 1e4a73902cc..29af296636d 100644 --- a/opencga-client/src/main/python/pyopencga/rest_clients/clinical_analysis_client.py +++ b/opencga-client/src/main/python/pyopencga/rest_clients/clinical_analysis_client.py @@ -2,7 +2,7 @@ WARNING: AUTOGENERATED CODE This code was generated by a tool. - Autogenerated on: 2024-02-14 + Autogenerated on: 2024-03-25 Manual changes to this file may cause unexpected behavior in your application. Manual changes to this file will be overwritten if the code is regenerated. @@ -14,7 +14,7 @@ class ClinicalAnalysis(_ParentRestClient): """ This class contains methods for the 'Analysis - Clinical' webservices - Client version: 2.12.3-SNAPSHOT + Client version: 2.12.4-SNAPSHOT PATH: /{apiVersion}/analysis/clinical """ diff --git a/opencga-client/src/main/python/pyopencga/rest_clients/cohort_client.py b/opencga-client/src/main/python/pyopencga/rest_clients/cohort_client.py index 50af2a865a2..875876ab699 100644 --- a/opencga-client/src/main/python/pyopencga/rest_clients/cohort_client.py +++ b/opencga-client/src/main/python/pyopencga/rest_clients/cohort_client.py @@ -2,7 +2,7 @@ WARNING: AUTOGENERATED CODE This code was generated by a tool. - Autogenerated on: 2024-02-14 + Autogenerated on: 2024-03-25 Manual changes to this file may cause unexpected behavior in your application. Manual changes to this file will be overwritten if the code is regenerated. @@ -14,7 +14,7 @@ class Cohort(_ParentRestClient): """ This class contains methods for the 'Cohorts' webservices - Client version: 2.12.3-SNAPSHOT + Client version: 2.12.4-SNAPSHOT PATH: /{apiVersion}/cohorts """ diff --git a/opencga-client/src/main/python/pyopencga/rest_clients/disease_panel_client.py b/opencga-client/src/main/python/pyopencga/rest_clients/disease_panel_client.py index e234b2ff148..7be70ca7113 100644 --- a/opencga-client/src/main/python/pyopencga/rest_clients/disease_panel_client.py +++ b/opencga-client/src/main/python/pyopencga/rest_clients/disease_panel_client.py @@ -2,7 +2,7 @@ WARNING: AUTOGENERATED CODE This code was generated by a tool. - Autogenerated on: 2024-02-14 + Autogenerated on: 2024-03-25 Manual changes to this file may cause unexpected behavior in your application. Manual changes to this file will be overwritten if the code is regenerated. @@ -14,7 +14,7 @@ class DiseasePanel(_ParentRestClient): """ This class contains methods for the 'Disease Panels' webservices - Client version: 2.12.3-SNAPSHOT + Client version: 2.12.4-SNAPSHOT PATH: /{apiVersion}/panels """ diff --git a/opencga-client/src/main/python/pyopencga/rest_clients/family_client.py b/opencga-client/src/main/python/pyopencga/rest_clients/family_client.py index 4fd32087258..425881e96b0 100644 --- a/opencga-client/src/main/python/pyopencga/rest_clients/family_client.py +++ b/opencga-client/src/main/python/pyopencga/rest_clients/family_client.py @@ -2,7 +2,7 @@ WARNING: AUTOGENERATED CODE This code was generated by a tool. - Autogenerated on: 2024-02-14 + Autogenerated on: 2024-03-25 Manual changes to this file may cause unexpected behavior in your application. Manual changes to this file will be overwritten if the code is regenerated. @@ -14,7 +14,7 @@ class Family(_ParentRestClient): """ This class contains methods for the 'Families' webservices - Client version: 2.12.3-SNAPSHOT + Client version: 2.12.4-SNAPSHOT PATH: /{apiVersion}/families """ diff --git a/opencga-client/src/main/python/pyopencga/rest_clients/file_client.py b/opencga-client/src/main/python/pyopencga/rest_clients/file_client.py index 22e58ba63be..d96fe998afa 100644 --- a/opencga-client/src/main/python/pyopencga/rest_clients/file_client.py +++ b/opencga-client/src/main/python/pyopencga/rest_clients/file_client.py @@ -2,7 +2,7 @@ WARNING: AUTOGENERATED CODE This code was generated by a tool. - Autogenerated on: 2024-02-14 + Autogenerated on: 2024-03-25 Manual changes to this file may cause unexpected behavior in your application. Manual changes to this file will be overwritten if the code is regenerated. @@ -14,7 +14,7 @@ class File(_ParentRestClient): """ This class contains methods for the 'Files' webservices - Client version: 2.12.3-SNAPSHOT + Client version: 2.12.4-SNAPSHOT PATH: /{apiVersion}/files """ diff --git a/opencga-client/src/main/python/pyopencga/rest_clients/ga4gh_client.py b/opencga-client/src/main/python/pyopencga/rest_clients/ga4gh_client.py index b15c6e8bd76..812e44e861b 100644 --- a/opencga-client/src/main/python/pyopencga/rest_clients/ga4gh_client.py +++ b/opencga-client/src/main/python/pyopencga/rest_clients/ga4gh_client.py @@ -2,7 +2,7 @@ WARNING: AUTOGENERATED CODE This code was generated by a tool. - Autogenerated on: 2024-02-14 + Autogenerated on: 2024-03-25 Manual changes to this file may cause unexpected behavior in your application. Manual changes to this file will be overwritten if the code is regenerated. @@ -14,7 +14,7 @@ class GA4GH(_ParentRestClient): """ This class contains methods for the 'GA4GH' webservices - Client version: 2.12.3-SNAPSHOT + Client version: 2.12.4-SNAPSHOT PATH: /{apiVersion}/ga4gh """ diff --git a/opencga-client/src/main/python/pyopencga/rest_clients/individual_client.py b/opencga-client/src/main/python/pyopencga/rest_clients/individual_client.py index 3b393328993..f4c36a24698 100644 --- a/opencga-client/src/main/python/pyopencga/rest_clients/individual_client.py +++ b/opencga-client/src/main/python/pyopencga/rest_clients/individual_client.py @@ -2,7 +2,7 @@ WARNING: AUTOGENERATED CODE This code was generated by a tool. - Autogenerated on: 2024-02-14 + Autogenerated on: 2024-03-25 Manual changes to this file may cause unexpected behavior in your application. Manual changes to this file will be overwritten if the code is regenerated. @@ -14,7 +14,7 @@ class Individual(_ParentRestClient): """ This class contains methods for the 'Individuals' webservices - Client version: 2.12.3-SNAPSHOT + Client version: 2.12.4-SNAPSHOT PATH: /{apiVersion}/individuals """ diff --git a/opencga-client/src/main/python/pyopencga/rest_clients/job_client.py b/opencga-client/src/main/python/pyopencga/rest_clients/job_client.py index 1d5369c4639..a8c09497fba 100644 --- a/opencga-client/src/main/python/pyopencga/rest_clients/job_client.py +++ b/opencga-client/src/main/python/pyopencga/rest_clients/job_client.py @@ -2,7 +2,7 @@ WARNING: AUTOGENERATED CODE This code was generated by a tool. - Autogenerated on: 2024-02-14 + Autogenerated on: 2024-03-25 Manual changes to this file may cause unexpected behavior in your application. Manual changes to this file will be overwritten if the code is regenerated. @@ -14,7 +14,7 @@ class Job(_ParentRestClient): """ This class contains methods for the 'Jobs' webservices - Client version: 2.12.3-SNAPSHOT + Client version: 2.12.4-SNAPSHOT PATH: /{apiVersion}/jobs """ diff --git a/opencga-client/src/main/python/pyopencga/rest_clients/meta_client.py b/opencga-client/src/main/python/pyopencga/rest_clients/meta_client.py index 1506926345b..dc6c21f3684 100644 --- a/opencga-client/src/main/python/pyopencga/rest_clients/meta_client.py +++ b/opencga-client/src/main/python/pyopencga/rest_clients/meta_client.py @@ -2,7 +2,7 @@ WARNING: AUTOGENERATED CODE This code was generated by a tool. - Autogenerated on: 2024-02-14 + Autogenerated on: 2024-03-25 Manual changes to this file may cause unexpected behavior in your application. Manual changes to this file will be overwritten if the code is regenerated. @@ -14,7 +14,7 @@ class Meta(_ParentRestClient): """ This class contains methods for the 'Meta' webservices - Client version: 2.12.3-SNAPSHOT + Client version: 2.12.4-SNAPSHOT PATH: /{apiVersion}/meta """ diff --git a/opencga-client/src/main/python/pyopencga/rest_clients/project_client.py b/opencga-client/src/main/python/pyopencga/rest_clients/project_client.py index 338e65d466c..4bf5c4fc14c 100644 --- a/opencga-client/src/main/python/pyopencga/rest_clients/project_client.py +++ b/opencga-client/src/main/python/pyopencga/rest_clients/project_client.py @@ -2,7 +2,7 @@ WARNING: AUTOGENERATED CODE This code was generated by a tool. - Autogenerated on: 2024-02-14 + Autogenerated on: 2024-03-25 Manual changes to this file may cause unexpected behavior in your application. Manual changes to this file will be overwritten if the code is regenerated. @@ -14,7 +14,7 @@ class Project(_ParentRestClient): """ This class contains methods for the 'Projects' webservices - Client version: 2.12.3-SNAPSHOT + Client version: 2.12.4-SNAPSHOT PATH: /{apiVersion}/projects """ diff --git a/opencga-client/src/main/python/pyopencga/rest_clients/sample_client.py b/opencga-client/src/main/python/pyopencga/rest_clients/sample_client.py index e83e98d3be2..17afff524c7 100644 --- a/opencga-client/src/main/python/pyopencga/rest_clients/sample_client.py +++ b/opencga-client/src/main/python/pyopencga/rest_clients/sample_client.py @@ -2,7 +2,7 @@ WARNING: AUTOGENERATED CODE This code was generated by a tool. - Autogenerated on: 2024-02-14 + Autogenerated on: 2024-03-25 Manual changes to this file may cause unexpected behavior in your application. Manual changes to this file will be overwritten if the code is regenerated. @@ -14,7 +14,7 @@ class Sample(_ParentRestClient): """ This class contains methods for the 'Samples' webservices - Client version: 2.12.3-SNAPSHOT + Client version: 2.12.4-SNAPSHOT PATH: /{apiVersion}/samples """ diff --git a/opencga-client/src/main/python/pyopencga/rest_clients/study_client.py b/opencga-client/src/main/python/pyopencga/rest_clients/study_client.py index 17fda942ec7..e7b18fa58fa 100644 --- a/opencga-client/src/main/python/pyopencga/rest_clients/study_client.py +++ b/opencga-client/src/main/python/pyopencga/rest_clients/study_client.py @@ -2,7 +2,7 @@ WARNING: AUTOGENERATED CODE This code was generated by a tool. - Autogenerated on: 2024-02-14 + Autogenerated on: 2024-03-25 Manual changes to this file may cause unexpected behavior in your application. Manual changes to this file will be overwritten if the code is regenerated. @@ -14,7 +14,7 @@ class Study(_ParentRestClient): """ This class contains methods for the 'Studies' webservices - Client version: 2.12.3-SNAPSHOT + Client version: 2.12.4-SNAPSHOT PATH: /{apiVersion}/studies """ diff --git a/opencga-client/src/main/python/pyopencga/rest_clients/user_client.py b/opencga-client/src/main/python/pyopencga/rest_clients/user_client.py index f991cf25dae..80c2f376458 100644 --- a/opencga-client/src/main/python/pyopencga/rest_clients/user_client.py +++ b/opencga-client/src/main/python/pyopencga/rest_clients/user_client.py @@ -2,7 +2,7 @@ WARNING: AUTOGENERATED CODE This code was generated by a tool. - Autogenerated on: 2024-02-14 + Autogenerated on: 2024-03-25 Manual changes to this file may cause unexpected behavior in your application. Manual changes to this file will be overwritten if the code is regenerated. @@ -14,7 +14,7 @@ class User(_ParentRestClient): """ This class contains methods for the 'Users' webservices - Client version: 2.12.3-SNAPSHOT + Client version: 2.12.4-SNAPSHOT PATH: /{apiVersion}/users """ diff --git a/opencga-client/src/main/python/pyopencga/rest_clients/variant_client.py b/opencga-client/src/main/python/pyopencga/rest_clients/variant_client.py index 57cd7a1a9cf..8beb31d9b2d 100644 --- a/opencga-client/src/main/python/pyopencga/rest_clients/variant_client.py +++ b/opencga-client/src/main/python/pyopencga/rest_clients/variant_client.py @@ -2,7 +2,7 @@ WARNING: AUTOGENERATED CODE This code was generated by a tool. - Autogenerated on: 2024-02-14 + Autogenerated on: 2024-03-25 Manual changes to this file may cause unexpected behavior in your application. Manual changes to this file will be overwritten if the code is regenerated. @@ -14,7 +14,7 @@ class Variant(_ParentRestClient): """ This class contains methods for the 'Analysis - Variant' webservices - Client version: 2.12.3-SNAPSHOT + Client version: 2.12.4-SNAPSHOT PATH: /{apiVersion}/analysis/variant """ diff --git a/opencga-client/src/main/python/pyopencga/rest_clients/variant_operation_client.py b/opencga-client/src/main/python/pyopencga/rest_clients/variant_operation_client.py index b48bb9d8ad4..a98d1fe2e4f 100644 --- a/opencga-client/src/main/python/pyopencga/rest_clients/variant_operation_client.py +++ b/opencga-client/src/main/python/pyopencga/rest_clients/variant_operation_client.py @@ -2,7 +2,7 @@ WARNING: AUTOGENERATED CODE This code was generated by a tool. - Autogenerated on: 2024-02-14 + Autogenerated on: 2024-03-25 Manual changes to this file may cause unexpected behavior in your application. Manual changes to this file will be overwritten if the code is regenerated. @@ -14,7 +14,7 @@ class VariantOperation(_ParentRestClient): """ This class contains methods for the 'Operations - Variant Storage' webservices - Client version: 2.12.3-SNAPSHOT + Client version: 2.12.4-SNAPSHOT PATH: /{apiVersion}/operation """ diff --git a/opencga-core/src/main/java/org/opencb/opencga/core/api/FieldConstants.java b/opencga-core/src/main/java/org/opencb/opencga/core/api/FieldConstants.java index d5476e10f60..dffc6bbe11e 100644 --- a/opencga-core/src/main/java/org/opencb/opencga/core/api/FieldConstants.java +++ b/opencga-core/src/main/java/org/opencb/opencga/core/api/FieldConstants.java @@ -485,6 +485,16 @@ public class FieldConstants { public static final String VARIANT_STATS_DESCRIPTION_DESCRIPTION = "Variant stats description."; public static final String VARIANT_STATS_QUERY_DESCRIPTION = "Variant stats query in JSON format."; + // Alignment index parameter descriptions + public static final String ALIGNMENT_INDEX_FILE_ID_DESCRIPTION = "File ID, (i.e., BAM/CRAM file ID)."; + public static final String ALIGNMENT_INDEX_OVERWRITE_DESCRIPTION = "Flag to force indexing."; + + // Coverage index parameter descriptions + public static final String COVERAGE_INDEX_BAM_FILE_ID_DESCRIPTION = "BAM file ID."; + public static final String COVERAGE_INDEX_BAI_FILE_ID_DESCRIPTION = "BAI file ID."; + public static final String COVERAGE_INDEX_OVERWRITE_DESCRIPTION = "Window size (i.e., the size of the bins, in bases, for the output" + + " of the BIGWIG file)."; + // Alignment QC analysis (asample-qc-run) public static final String ALIGNMENT_QC_BAM_FILE_DESCRIPTION = "ID for the BAM file to process."; public static final String ALIGNMENT_QC_SKIP_DESCRIPTION = "To skip any alignment QC metrics use the following keywords (separated by" diff --git a/opencga-core/src/main/java/org/opencb/opencga/core/models/alignment/AlignmentIndexParams.java b/opencga-core/src/main/java/org/opencb/opencga/core/models/alignment/AlignmentIndexParams.java index 741d089c2f0..43bc73f7931 100644 --- a/opencga-core/src/main/java/org/opencb/opencga/core/models/alignment/AlignmentIndexParams.java +++ b/opencga-core/src/main/java/org/opencb/opencga/core/models/alignment/AlignmentIndexParams.java @@ -1,11 +1,16 @@ package org.opencb.opencga.core.models.alignment; +import org.opencb.commons.annotations.DataField; +import org.opencb.opencga.core.api.FieldConstants; import org.opencb.opencga.core.tools.ToolParams; public class AlignmentIndexParams extends ToolParams { public static final String DESCRIPTION = "Alignment index params"; + @DataField(id = "fileId", description = FieldConstants.ALIGNMENT_INDEX_FILE_ID_DESCRIPTION, required = true) private String fileId; + + @DataField(id = "overwrite", description = FieldConstants.ALIGNMENT_INDEX_OVERWRITE_DESCRIPTION) private boolean overwrite; public AlignmentIndexParams() { diff --git a/opencga-core/src/main/java/org/opencb/opencga/core/models/alignment/CoverageIndexParams.java b/opencga-core/src/main/java/org/opencb/opencga/core/models/alignment/CoverageIndexParams.java index f655829625d..9ce861660f2 100644 --- a/opencga-core/src/main/java/org/opencb/opencga/core/models/alignment/CoverageIndexParams.java +++ b/opencga-core/src/main/java/org/opencb/opencga/core/models/alignment/CoverageIndexParams.java @@ -2,15 +2,22 @@ import com.fasterxml.jackson.annotation.JsonProperty; +import org.opencb.commons.annotations.DataField; +import org.opencb.opencga.core.api.FieldConstants; +import org.opencb.opencga.core.api.ParamConstants; import org.opencb.opencga.core.tools.ToolParams; public class CoverageIndexParams extends ToolParams { public static final String DESCRIPTION = "Coverage computation parameters"; + @DataField(id = "bamFileId", description = FieldConstants.COVERAGE_INDEX_BAM_FILE_ID_DESCRIPTION, required = true) private String bamFileId; + + @DataField(id = "baiFileId", description = FieldConstants.COVERAGE_INDEX_BAI_FILE_ID_DESCRIPTION) private String baiFileId; - @JsonProperty(defaultValue = "1") + @DataField(id = "windowSize", description = FieldConstants.COVERAGE_INDEX_OVERWRITE_DESCRIPTION, + defaultValue = ParamConstants.COVERAGE_WINDOW_SIZE_DEFAULT) private int windowSize; public CoverageIndexParams() { diff --git a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/alignment/AlignmentStorageOptions.java b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/alignment/AlignmentStorageOptions.java index 672a7f03bca..a137d4c4e0f 100644 --- a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/alignment/AlignmentStorageOptions.java +++ b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/alignment/AlignmentStorageOptions.java @@ -1,11 +1,11 @@ package org.opencb.opencga.storage.core.alignment; -import org.opencb.biodata.tools.alignment.BamManager; +import org.opencb.opencga.core.api.ParamConstants; import org.opencb.opencga.core.config.ConfigurationOption; public enum AlignmentStorageOptions implements ConfigurationOption { - BIG_WIG_WINDOWS_SIZE("bigWigWindowsSize", BamManager.DEFAULT_WINDOW_SIZE); + BIG_WIG_WINDOWS_SIZE("bigWigWindowsSize", ParamConstants.COVERAGE_WINDOW_SIZE_DEFAULT); private final String key; private final Object value; From f26c9e8e343aee8f22d2e398722a73f42012130a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joaqu=C3=ADn=20T=C3=A1rraga=20Gim=C3=A9nez?= Date: Mon, 25 Mar 2024 15:17:48 +0100 Subject: [PATCH 12/85] core: fix Integer conversion, #TASK-5858 --- .../core/alignment/local/LocalAlignmentStoragePipeline.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/alignment/local/LocalAlignmentStoragePipeline.java b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/alignment/local/LocalAlignmentStoragePipeline.java index 009718fcbfb..d45ccbc130c 100644 --- a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/alignment/local/LocalAlignmentStoragePipeline.java +++ b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/alignment/local/LocalAlignmentStoragePipeline.java @@ -87,7 +87,7 @@ public URI transform(URI input, URI pedigree, URI output) throws Exception { // 3) Create the BigWig file containing the coverage using the bamCoverage from the DeepTools package Path bwPath = workspace.resolve(path.getFileName() + BamManager.COVERAGE_BIGWIG_EXTENSION); int windowSize = configuration.getInt(AlignmentStorageOptions.BIG_WIG_WINDOWS_SIZE.key(), - AlignmentStorageOptions.BIG_WIG_WINDOWS_SIZE.defaultValue()); + Integer.parseInt(AlignmentStorageOptions.BIG_WIG_WINDOWS_SIZE.defaultValue())); bamManager.calculateBigWigCoverage(bwPath, windowSize); return input; From 1e5f15b67fb6bc76e136a71802f8aee7574652c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joaqu=C3=ADn=20T=C3=A1rraga=20Gim=C3=A9nez?= Date: Mon, 25 Mar 2024 15:23:57 +0100 Subject: [PATCH 13/85] analysis: remove jobID check from OpenCgaTool, #TASK-5858 --- .../analysis/alignment/AlignmentCoverageAnalysis.java | 4 ++++ .../analysis/alignment/AlignmentIndexOperation.java | 10 ++++++++++ .../org/opencb/opencga/analysis/tools/OpenCgaTool.java | 3 --- 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/opencga-analysis/src/main/java/org/opencb/opencga/analysis/alignment/AlignmentCoverageAnalysis.java b/opencga-analysis/src/main/java/org/opencb/opencga/analysis/alignment/AlignmentCoverageAnalysis.java index b089541591a..ce7b82a7dba 100644 --- a/opencga-analysis/src/main/java/org/opencb/opencga/analysis/alignment/AlignmentCoverageAnalysis.java +++ b/opencga-analysis/src/main/java/org/opencb/opencga/analysis/alignment/AlignmentCoverageAnalysis.java @@ -54,6 +54,10 @@ protected void check() throws Exception { super.check(); // Sanity check + if (StringUtils.isEmpty(getJobId())) { + throw new ToolException("Missing job ID"); + } + if (StringUtils.isEmpty(getStudy())) { throw new ToolException("Missing study when computing alignment coverage"); } diff --git a/opencga-analysis/src/main/java/org/opencb/opencga/analysis/alignment/AlignmentIndexOperation.java b/opencga-analysis/src/main/java/org/opencb/opencga/analysis/alignment/AlignmentIndexOperation.java index 6f9fdf7bce7..0c597a6a8f4 100644 --- a/opencga-analysis/src/main/java/org/opencb/opencga/analysis/alignment/AlignmentIndexOperation.java +++ b/opencga-analysis/src/main/java/org/opencb/opencga/analysis/alignment/AlignmentIndexOperation.java @@ -16,6 +16,7 @@ package org.opencb.opencga.analysis.alignment; +import org.apache.commons.lang3.StringUtils; import org.opencb.biodata.tools.alignment.BamManager; import org.opencb.commons.datastore.core.QueryOptions; import org.opencb.opencga.analysis.tools.OpenCgaTool; @@ -52,6 +53,15 @@ public class AlignmentIndexOperation extends OpenCgaToolScopeStudy { protected void check() throws Exception { super.check(); + // Sanity check + if (StringUtils.isEmpty(getJobId())) { + throw new ToolException("Missing job ID"); + } + + if (StringUtils.isEmpty(getStudy())) { + throw new ToolException("Missing study when computing alignment index"); + } + OpenCGAResult fileResult; try { fileResult = catalogManager.getFileManager().get(getStudy(), indexParams.getFileId(), QueryOptions.empty(), token); diff --git a/opencga-analysis/src/main/java/org/opencb/opencga/analysis/tools/OpenCgaTool.java b/opencga-analysis/src/main/java/org/opencb/opencga/analysis/tools/OpenCgaTool.java index 835a0c92259..7769315137b 100644 --- a/opencga-analysis/src/main/java/org/opencb/opencga/analysis/tools/OpenCgaTool.java +++ b/opencga-analysis/src/main/java/org/opencb/opencga/analysis/tools/OpenCgaTool.java @@ -317,9 +317,6 @@ private void privateCheck() throws Exception { * @throws Exception if the parameters are not correct */ protected void check() throws Exception { - if (StringUtils.isEmpty(jobId)) { - throw new IllegalArgumentException("Missing job ID"); - } } /** From 7756021c9afcab503c694438cfdad97c82b45fff Mon Sep 17 00:00:00 2001 From: pfurio Date: Thu, 28 Mar 2024 10:15:01 +0100 Subject: [PATCH 14/85] catalog: replace status.name indexes, #TASK-5796 --- .../catalog/FixStatusIndexesMigration.java | 46 +++++++++++++++++++ .../src/main/resources/catalog-indexes.txt | 32 ++++++------- 2 files changed, 62 insertions(+), 16 deletions(-) create mode 100644 opencga-app/src/main/java/org/opencb/opencga/app/migrations/v2_12_4/catalog/FixStatusIndexesMigration.java diff --git a/opencga-app/src/main/java/org/opencb/opencga/app/migrations/v2_12_4/catalog/FixStatusIndexesMigration.java b/opencga-app/src/main/java/org/opencb/opencga/app/migrations/v2_12_4/catalog/FixStatusIndexesMigration.java new file mode 100644 index 00000000000..bce2551a0f5 --- /dev/null +++ b/opencga-app/src/main/java/org/opencb/opencga/app/migrations/v2_12_4/catalog/FixStatusIndexesMigration.java @@ -0,0 +1,46 @@ +package org.opencb.opencga.app.migrations.v2_12_4.catalog; + +import org.bson.Document; +import org.opencb.opencga.catalog.db.mongodb.MongoDBAdaptorFactory; +import org.opencb.opencga.catalog.migration.Migration; +import org.opencb.opencga.catalog.migration.MigrationTool; + +import java.util.Arrays; + +@Migration(id = "fix_status_indexes" , + description = "Replace 'status.name' indexes for 'status.id'", + version = "2.12.4", + domain = Migration.MigrationDomain.CATALOG, + language = Migration.MigrationLanguage.JAVA, + date = 20240328 +) +public class FixStatusIndexesMigration extends MigrationTool { + + @Override + protected void run() throws Exception { + Document statusIndex = new Document() + .append("status.name", 1) + .append("studyUid", 1); + dropIndex(Arrays.asList(MongoDBAdaptorFactory.JOB_COLLECTION, MongoDBAdaptorFactory.FILE_COLLECTION, + MongoDBAdaptorFactory.SAMPLE_COLLECTION, MongoDBAdaptorFactory.SAMPLE_ARCHIVE_COLLECTION, + MongoDBAdaptorFactory.COHORT_COLLECTION, MongoDBAdaptorFactory.INDIVIDUAL_COLLECTION, + MongoDBAdaptorFactory.INDIVIDUAL_ARCHIVE_COLLECTION, MongoDBAdaptorFactory.FAMILY_COLLECTION, + MongoDBAdaptorFactory.FAMILY_ARCHIVE_COLLECTION, MongoDBAdaptorFactory.PANEL_COLLECTION, + MongoDBAdaptorFactory.PANEL_ARCHIVE_COLLECTION), statusIndex); + + Document internalStatusIndex = new Document() + .append("internal.status.name", 1) + .append("studyUid", 1); + dropIndex(Arrays.asList(MongoDBAdaptorFactory.JOB_COLLECTION, MongoDBAdaptorFactory.FILE_COLLECTION, + MongoDBAdaptorFactory.SAMPLE_COLLECTION, MongoDBAdaptorFactory.SAMPLE_ARCHIVE_COLLECTION, + MongoDBAdaptorFactory.COHORT_COLLECTION, MongoDBAdaptorFactory.INDIVIDUAL_COLLECTION, + MongoDBAdaptorFactory.INDIVIDUAL_ARCHIVE_COLLECTION, MongoDBAdaptorFactory.FAMILY_COLLECTION, + MongoDBAdaptorFactory.FAMILY_ARCHIVE_COLLECTION, MongoDBAdaptorFactory.PANEL_COLLECTION, + MongoDBAdaptorFactory.PANEL_ARCHIVE_COLLECTION, MongoDBAdaptorFactory.CLINICAL_ANALYSIS_COLLECTION, + MongoDBAdaptorFactory.INTERPRETATION_COLLECTION, MongoDBAdaptorFactory.INTERPRETATION_ARCHIVE_COLLECTION), + internalStatusIndex); + + catalogManager.installIndexes(token); + } + +} diff --git a/opencga-catalog/src/main/resources/catalog-indexes.txt b/opencga-catalog/src/main/resources/catalog-indexes.txt index 996eeb67534..4eeafe1f865 100644 --- a/opencga-catalog/src/main/resources/catalog-indexes.txt +++ b/opencga-catalog/src/main/resources/catalog-indexes.txt @@ -25,8 +25,8 @@ {"collections": ["job"], "fields": {"outDir.uid": 1, "studyUid": 1}, "options": {}} {"collections": ["job"], "fields": {"tags": 1, "studyUid": 1}, "options": {}} {"collections": ["job"], "fields": {"visited": 1, "studyUid": 1}, "options": {}} -{"collections": ["job"], "fields": {"status.name": 1, "studyUid": 1}, "options": {}} -{"collections": ["job"], "fields": {"internal.status.name": 1, "studyUid": 1}, "options": {}} +{"collections": ["job"], "fields": {"internal.status.id": 1, "studyUid": 1}, "options": {}} +{"collections": ["job"], "fields": {"internal.status.id": 1, "_priority": 1, "_creationDate": 1}, "options": {}} {"collections": ["job"], "fields": {"_priority": 1, "_creationDate": 1, "studyUid": 1}, "options": {}} {"collections": ["job"], "fields": {"_priority": 1, "studyUid": 1}, "options": {}} {"collections": ["job"], "fields": {"_creationDate": 1, "studyUid": 1}, "options": {}} @@ -53,8 +53,8 @@ {"collections": ["file"], "fields": {"_creationDate": 1, "studyUid": 1}, "options": {}} {"collections": ["file"], "fields": {"_modificationDate": 1, "studyUid": 1}, "options": {}} {"collections": ["file"], "fields": {"jobId": 1, "studyUid": 1}, "options": {}} -{"collections": ["file"], "fields": {"status.name": 1, "studyUid": 1}, "options": {}} -{"collections": ["file"], "fields": {"internal.status.name": 1, "studyUid": 1}, "options": {}} +{"collections": ["file"], "fields": {"status.id": 1, "studyUid": 1}, "options": {}} +{"collections": ["file"], "fields": {"internal.status.id": 1, "studyUid": 1}, "options": {}} {"collections": ["file"], "fields": {"internal.variant.index.status.id": 1, "studyUid": 1}, "options": {}} {"collections": ["file"], "fields": {"studyUid": 1, "_acl": 1}, "options": {}} {"collections": ["file"], "fields": {"studyUid": 1, "release": 1, "_acl": 1}, "options": {}} @@ -92,8 +92,8 @@ {"collections": ["sample", "sample_archive"], "fields": {"_ias.as": 1, "studyUid": 1}, "options": {}} {"collections": ["sample", "sample_archive"], "fields": {"_ias.vs": 1, "studyUid": 1}, "options": {}} {"collections": ["sample", "sample_archive"], "fields": {"_ias.id": 1, "_ias.value": 1, "studyUid": 1}, "options": {}} -{"collections": ["sample", "sample_archive"], "fields": {"internal.status.name": 1, "studyUid": 1}, "options": {}} -{"collections": ["sample", "sample_archive"], "fields": {"status.name": 1, "studyUid": 1}, "options": {}} +{"collections": ["sample", "sample_archive"], "fields": {"internal.status.id": 1, "studyUid": 1}, "options": {}} +{"collections": ["sample", "sample_archive"], "fields": {"status.id": 1, "studyUid": 1}, "options": {}} {"collections": ["sample", "sample_archive"], "fields": {"internal.rga.status": 1, "studyUid": 1}, "options": {}} {"collections": ["individual", "individual_archive"], "fields": {"uuid": 1, "version": 1}, "options": {"unique": true}} @@ -126,8 +126,8 @@ {"collections": ["individual", "individual_archive"], "fields": {"_ias.as": 1, "studyUid": 1}, "options": {}} {"collections": ["individual", "individual_archive"], "fields": {"_ias.vs": 1, "studyUid": 1}, "options": {}} {"collections": ["individual", "individual_archive"], "fields": {"_ias.id": 1, "_ias.value": 1, "studyUid": 1}, "options": {}} -{"collections": ["individual", "individual_archive"], "fields": {"status.name": 1, "studyUid": 1}, "options": {}} -{"collections": ["individual", "individual_archive"], "fields": {"internal.status.name": 1, "studyUid": 1}, "options": {}} +{"collections": ["individual", "individual_archive"], "fields": {"status.id": 1, "studyUid": 1}, "options": {}} +{"collections": ["individual", "individual_archive"], "fields": {"internal.status.id": 1, "studyUid": 1}, "options": {}} {"collections": ["cohort"], "fields": {"uuid": 1}, "options": {"unique": true}} {"collections": ["cohort"], "fields": {"uid": 1}, "options": {"unique": true}} @@ -146,8 +146,8 @@ {"collections": ["cohort"], "fields": {"_ias.as": 1, "studyUid": 1}, "options": {}} {"collections": ["cohort"], "fields": {"_ias.vs": 1, "studyUid": 1}, "options": {}} {"collections": ["cohort"], "fields": {"_ias.id": 1, "_ias.value": 1, "studyUid": 1}, "options": {}} -{"collections": ["cohort"], "fields": {"status.name": 1, "studyUid": 1}, "options": {}} -{"collections": ["cohort"], "fields": {"internal.status.name": 1, "studyUid": 1}, "options": {}} +{"collections": ["cohort"], "fields": {"status.id": 1, "studyUid": 1}, "options": {}} +{"collections": ["cohort"], "fields": {"internal.status.id": 1, "studyUid": 1}, "options": {}} {"collections": ["family", "family_archive"], "fields": {"uuid": 1, "version": 1}, "options": {"unique": true}} {"collections": ["family", "family_archive"], "fields": {"uid": 1, "version": 1}, "options": {"unique": true}} @@ -170,8 +170,8 @@ {"collections": ["family", "family_archive"], "fields": {"_ias.as": 1, "studyUid": 1}, "options": {}} {"collections": ["family", "family_archive"], "fields": {"_ias.vs": 1, "studyUid": 1}, "options": {}} {"collections": ["family", "family_archive"], "fields": {"_ias.id": 1, "_ias.value": 1, "studyUid": 1}, "options": {}} -{"collections": ["family", "family_archive"], "fields": {"status.name": 1, "studyUid": 1}, "options": {}} -{"collections": ["family", "family_archive"], "fields": {"internal.status.name": 1, "studyUid": 1}, "options": {}} +{"collections": ["family", "family_archive"], "fields": {"status.id": 1, "studyUid": 1}, "options": {}} +{"collections": ["family", "family_archive"], "fields": {"internal.status.id": 1, "studyUid": 1}, "options": {}} {"collections": ["panel", "panel_archive"], "fields": {"uuid": 1, "version": 1}, "options": {"unique": true}} {"collections": ["panel", "panel_archive"], "fields": {"uid": 1, "version": 1}, "options": {"unique": true}} @@ -189,11 +189,11 @@ {"collections": ["panel", "panel_archive"], "fields": {"categories.name": 1, "studyUid": 1}, "options": {}} {"collections": ["panel", "panel_archive"], "fields": {"_creationDate": 1, "studyUid": 1}, "options": {}} {"collections": ["panel", "panel_archive"], "fields": {"_modificationDate": 1, "studyUid": 1}, "options": {}} -{"collections": ["panel", "panel_archive"], "fields": {"status.name": 1, "studyUid": 1}, "options": {}} +{"collections": ["panel", "panel_archive"], "fields": {"status.id": 1, "studyUid": 1}, "options": {}} {"collections": ["panel", "panel_archive"], "fields": {"studyUid": 1, "_lastOfVersion": 1, "_acl": 1}, "options": {}} {"collections": ["panel", "panel_archive"], "fields": {"studyUid": 1, "_releaseFromVersion": 1, "_lastOfRelease": 1}, "options": {}} {"collections": ["panel", "panel_archive"], "fields": {"studyUid": 1, "release": 1, "_acl": 1}, "options": {}} -{"collections": ["panel", "panel_archive"], "fields": {"internal.status.name": 1, "studyUid": 1}, "options": {}} +{"collections": ["panel", "panel_archive"], "fields": {"internal.status.id": 1, "studyUid": 1}, "options": {}} {"collections": ["clinical"], "fields": {"id": 1, "studyUid": 1}, "options": {"unique": true}} {"collections": ["clinical"], "fields": {"uuid": 1}, "options": {"unique": true}} @@ -219,7 +219,7 @@ {"collections": ["clinical"], "fields": {"_modificationDate": 1, "studyUid": 1}, "options": {}} {"collections": ["clinical"], "fields": {"studyUid": 1, "_acl": 1}, "options": {}} {"collections": ["clinical"], "fields": {"status.id": 1, "studyUid": 1}, "options": {}} -{"collections": ["clinical"], "fields": {"internal.status.name": 1, "studyUid": 1}, "options": {}} +{"collections": ["clinical"], "fields": {"internal.status.id": 1, "studyUid": 1}, "options": {}} {"collections": ["interpretation", "interpretation_archive"], "fields": {"uuid": 1, "version": 1}, "options": {"unique": true}} {"collections": ["interpretation", "interpretation_archive"], "fields": {"uid": 1, "version": 1}, "options": {"unique": true}} @@ -234,7 +234,7 @@ {"collections": ["interpretation", "interpretation_archive"], "fields": {"_creationDate": 1, "studyUid": 1}, "options": {}} {"collections": ["interpretation", "interpretation_archive"], "fields": {"_modificationDate": 1, "studyUid": 1}, "options": {}} {"collections": ["interpretation", "interpretation_archive"], "fields": {"status.id": 1, "studyUid": 1}, "options": {}} -{"collections": ["interpretation", "interpretation_archive"], "fields": {"internal.status.name": 1, "studyUid": 1}, "options": {}} +{"collections": ["interpretation", "interpretation_archive"], "fields": {"internal.status.id": 1, "studyUid": 1}, "options": {}} {"collections": ["interpretation", "interpretation_archive"], "fields": {"studyUid": 1, "_lastOfVersion": 1}, "options": {}} {"collections": ["interpretation", "interpretation_archive"], "fields": {"studyUid": 1, "_releaseFromVersion": 1, "_lastOfRelease": 1}, "options": {}} {"collections": ["interpretation", "interpretation_archive"], "fields": {"studyUid": 1, "release": 1}, "options": {}} From 29e75fe994c7b512387b7765f186a5937f00bbfe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joaqu=C3=ADn=20T=C3=A1rraga=20Gim=C3=A9nez?= Date: Tue, 2 Apr 2024 12:32:00 +0200 Subject: [PATCH 15/85] analysis: take into account the clinical analysis type before running the Exomiser analysis; and add JUnit test, #TASK-5603 --- .../ExomiserInterpretationAnalysis.java | 10 +++ .../exomiser/ExomiserWrapperAnalysis.java | 1 + .../ExomiserWrapperAnalysisExecutor.java | 41 +++++++----- .../ExomiserInterpretationAnalysisTest.java | 33 +++++++++- .../VariantInternalCommandExecutor.java | 2 + .../options/VariantCommandOptions.java | 4 ++ .../managers/AbstractClinicalManagerTest.java | 59 ++++++++++++++++-- .../test/resources/biofiles/HG104.1k.vcf.gz | Bin 0 -> 24986 bytes .../test/resources/biofiles/HG105.1k.vcf.gz | Bin 0 -> 27768 bytes .../test/resources/biofiles/HG106.1k.vcf.gz | Bin 0 -> 24417 bytes .../test/resources/biofiles/HG107.1k.vcf.gz | Bin 0 -> 24985 bytes .../clinical/ExomiserWrapperParams.java | 14 ++++- 12 files changed, 142 insertions(+), 22 deletions(-) create mode 100644 opencga-catalog/src/test/resources/biofiles/HG104.1k.vcf.gz create mode 100644 opencga-catalog/src/test/resources/biofiles/HG105.1k.vcf.gz create mode 100644 opencga-catalog/src/test/resources/biofiles/HG106.1k.vcf.gz create mode 100644 opencga-catalog/src/test/resources/biofiles/HG107.1k.vcf.gz diff --git a/opencga-analysis/src/main/java/org/opencb/opencga/analysis/clinical/exomiser/ExomiserInterpretationAnalysis.java b/opencga-analysis/src/main/java/org/opencb/opencga/analysis/clinical/exomiser/ExomiserInterpretationAnalysis.java index 39fa4fd581c..0ae02104c82 100644 --- a/opencga-analysis/src/main/java/org/opencb/opencga/analysis/clinical/exomiser/ExomiserInterpretationAnalysis.java +++ b/opencga-analysis/src/main/java/org/opencb/opencga/analysis/clinical/exomiser/ExomiserInterpretationAnalysis.java @@ -68,6 +68,7 @@ public class ExomiserInterpretationAnalysis extends InterpretationAnalysis { private String studyId; private String clinicalAnalysisId; private String sampleId; + private ClinicalAnalysis.Type clinicalAnalysisType; private ClinicalAnalysis clinicalAnalysis; @@ -116,6 +117,14 @@ protected void check() throws Exception { } sampleId = clinicalAnalysis.getProband().getSamples().get(0).getId(); + if (clinicalAnalysis.getType() == ClinicalAnalysis.Type.FAMILY) { + clinicalAnalysisType = ClinicalAnalysis.Type.FAMILY; + } else { + clinicalAnalysisType = ClinicalAnalysis.Type.SINGLE; + } + logger.info("The clinical analysis type is {}, so the Exomiser will be run in mode {}", clinicalAnalysis.getType(), + clinicalAnalysisType); + // Update executor params with OpenCGA home and session ID setUpStorageEngineExecutor(studyId); } @@ -128,6 +137,7 @@ protected void run() throws ToolException { getToolExecutor(ExomiserWrapperAnalysisExecutor.class) .setStudyId(studyId) .setSampleId(sampleId) + .setClinicalAnalysisType(clinicalAnalysisType) .execute(); saveInterpretation(studyId, clinicalAnalysis); diff --git a/opencga-analysis/src/main/java/org/opencb/opencga/analysis/wrappers/exomiser/ExomiserWrapperAnalysis.java b/opencga-analysis/src/main/java/org/opencb/opencga/analysis/wrappers/exomiser/ExomiserWrapperAnalysis.java index 3d8253861a4..172f8629135 100644 --- a/opencga-analysis/src/main/java/org/opencb/opencga/analysis/wrappers/exomiser/ExomiserWrapperAnalysis.java +++ b/opencga-analysis/src/main/java/org/opencb/opencga/analysis/wrappers/exomiser/ExomiserWrapperAnalysis.java @@ -52,6 +52,7 @@ protected void run() throws Exception { getToolExecutor(ExomiserWrapperAnalysisExecutor.class) .setStudyId(study) .setSampleId(analysisParams.getSample()) + .setSampleId(analysisParams.getSample()) .execute(); }); } diff --git a/opencga-analysis/src/main/java/org/opencb/opencga/analysis/wrappers/exomiser/ExomiserWrapperAnalysisExecutor.java b/opencga-analysis/src/main/java/org/opencb/opencga/analysis/wrappers/exomiser/ExomiserWrapperAnalysisExecutor.java index 86bb3760b3c..cdbb24c2ab8 100644 --- a/opencga-analysis/src/main/java/org/opencb/opencga/analysis/wrappers/exomiser/ExomiserWrapperAnalysisExecutor.java +++ b/opencga-analysis/src/main/java/org/opencb/opencga/analysis/wrappers/exomiser/ExomiserWrapperAnalysisExecutor.java @@ -18,6 +18,7 @@ import org.opencb.opencga.catalog.managers.FamilyManager; import org.opencb.opencga.core.exceptions.ToolException; import org.opencb.opencga.core.exceptions.ToolExecutorException; +import org.opencb.opencga.core.models.clinical.ClinicalAnalysis; import org.opencb.opencga.core.models.family.Family; import org.opencb.opencga.core.models.individual.Individual; import org.opencb.opencga.core.tools.annotations.ToolExecutor; @@ -50,6 +51,7 @@ public class ExomiserWrapperAnalysisExecutor extends DockerWrapperAnalysisExecut private String studyId; private String sampleId; + private ClinicalAnalysis.Type clinicalAnalysisType; private Logger logger = LoggerFactory.getLogger(this.getClass()); @@ -100,22 +102,24 @@ public void run() throws ToolException { // Check multi-sample (family) analysis File pedigreeFile = null; Pedigree pedigree = null; - if (individual.getMother() != null && individual.getMother().getId() != null - && individual.getFather() != null && individual.getFather().getId() != null) { - Family family = IndividualQcUtils.getFamilyByIndividualId(getStudyId(), individual.getId(), - getVariantStorageManager().getCatalogManager(), getToken()); - if (family != null) { - pedigree = FamilyManager.getPedigreeFromFamily(family, individual.getId()); - } - - if (pedigree != null) { - if (individual.getFather() != null) { - samples.add(individual.getFather().getSamples().get(0).getId()); + if (clinicalAnalysisType == ClinicalAnalysis.Type.FAMILY) { + if (individual.getMother() != null && individual.getMother().getId() != null + && individual.getFather() != null && individual.getFather().getId() != null) { + Family family = IndividualQcUtils.getFamilyByIndividualId(getStudyId(), individual.getId(), + getVariantStorageManager().getCatalogManager(), getToken()); + if (family != null) { + pedigree = FamilyManager.getPedigreeFromFamily(family, individual.getId()); } - if (individual.getMother() != null) { - samples.add(individual.getMother().getSamples().get(0).getId()); + + if (pedigree != null) { + if (individual.getFather() != null) { + samples.add(individual.getFather().getSamples().get(0).getId()); + } + if (individual.getMother() != null) { + samples.add(individual.getMother().getSamples().get(0).getId()); + } + pedigreeFile = createPedigreeFile(family, pedigree); } - pedigreeFile = createPedigreeFile(family, pedigree); } } File sampleFile = createSampleFile(individual, hpos, pedigree); @@ -483,4 +487,13 @@ public ExomiserWrapperAnalysisExecutor setSampleId(String sampleId) { this.sampleId = sampleId; return this; } + + public ClinicalAnalysis.Type getClinicalAnalysisType() { + return clinicalAnalysisType; + } + + public ExomiserWrapperAnalysisExecutor setClinicalAnalysisType(ClinicalAnalysis.Type clinicalAnalysisType) { + this.clinicalAnalysisType = clinicalAnalysisType; + return this; + } } diff --git a/opencga-analysis/src/test/java/org/opencb/opencga/analysis/clinical/exomiser/ExomiserInterpretationAnalysisTest.java b/opencga-analysis/src/test/java/org/opencb/opencga/analysis/clinical/exomiser/ExomiserInterpretationAnalysisTest.java index 001e44792cf..04d8147529b 100644 --- a/opencga-analysis/src/test/java/org/opencb/opencga/analysis/clinical/exomiser/ExomiserInterpretationAnalysisTest.java +++ b/opencga-analysis/src/test/java/org/opencb/opencga/analysis/clinical/exomiser/ExomiserInterpretationAnalysisTest.java @@ -71,7 +71,7 @@ public void testNormalization() throws NonStandardCompliantSampleField { } @Test - public void singleExomiserAnalysis() throws IOException, CatalogException, ToolException { + public void singleSingleExomiserAnalysis() throws IOException, CatalogException, ToolException { assumeThat(Paths.get("/opt/opencga/analysis/resources/exomiser").toFile().exists(), is(true)); prepareExomiserData(); @@ -98,11 +98,11 @@ public void singleExomiserAnalysis() throws IOException, CatalogException, ToolE } @Test - public void familyExomiserAnalysis() throws IOException, CatalogException, ToolException { + public void trioFamilyExomiserAnalysis() throws IOException, CatalogException, ToolException { assumeThat(Paths.get("/opt/opencga/analysis/resources/exomiser").toFile().exists(), is(true)); prepareExomiserData(); - outDir = Paths.get(opencga.createTmpOutdir("_interpretation_analysis_family")); + outDir = Paths.get(opencga.createTmpOutdir("_interpretation_analysis_trio_family")); ClinicalAnalysis clinicalAnalysis = clinicalTest.catalogManager.getClinicalAnalysisManager() .get(clinicalTest.studyFqn, clinicalTest.CA_ID3, QueryOptions.empty(), clinicalTest.token).first(); @@ -124,6 +124,33 @@ public void familyExomiserAnalysis() throws IOException, CatalogException, ToolE System.out.println("results at out dir = " + outDir.toAbsolutePath()); } + @Test + public void trioSingleExomiserAnalysis() throws IOException, CatalogException, ToolException { + assumeThat(Paths.get("/opt/opencga/analysis/resources/exomiser").toFile().exists(), is(true)); + + prepareExomiserData(); + outDir = Paths.get(opencga.createTmpOutdir("_interpretation_analysis_trio_single")); + + ClinicalAnalysis clinicalAnalysis = clinicalTest.catalogManager.getClinicalAnalysisManager() + .get(clinicalTest.studyFqn, clinicalTest.CA_ID4, QueryOptions.empty(), clinicalTest.token).first(); + assertEquals(0, clinicalAnalysis.getSecondaryInterpretations().size()); + + ExomiserInterpretationAnalysis exomiser = new ExomiserInterpretationAnalysis(); + + exomiser.setUp(opencga.getOpencgaHome().toAbsolutePath().toString(), new ObjectMap(), outDir, clinicalTest.token); + exomiser.setStudyId(clinicalTest.studyFqn) + .setClinicalAnalysisId(clinicalTest.CA_ID4); + + ExecutionResult result = exomiser.start(); + + // Refresh clinical analysis + clinicalAnalysis = clinicalTest.catalogManager.getClinicalAnalysisManager() + .get(clinicalTest.studyFqn, clinicalTest.CA_ID4, QueryOptions.empty(), clinicalTest.token).first(); + assertEquals(1, clinicalAnalysis.getSecondaryInterpretations().size()); + assertTrue(clinicalAnalysis.getSecondaryInterpretations().get(0).getPrimaryFindings().size() > 0); + System.out.println("results at out dir = " + outDir.toAbsolutePath()); + } + private void prepareExomiserData() throws IOException { Path opencgaHome = opencga.getOpencgaHome(); Path exomiserDataPath = opencgaHome.resolve("analysis/resources"); diff --git a/opencga-app/src/main/java/org/opencb/opencga/app/cli/internal/executors/VariantInternalCommandExecutor.java b/opencga-app/src/main/java/org/opencb/opencga/app/cli/internal/executors/VariantInternalCommandExecutor.java index e502850d9ee..34ee91a796e 100644 --- a/opencga-app/src/main/java/org/opencb/opencga/app/cli/internal/executors/VariantInternalCommandExecutor.java +++ b/opencga-app/src/main/java/org/opencb/opencga/app/cli/internal/executors/VariantInternalCommandExecutor.java @@ -62,6 +62,7 @@ import org.opencb.opencga.core.common.YesNoAuto; import org.opencb.opencga.core.exceptions.AnalysisExecutionException; import org.opencb.opencga.core.exceptions.ToolException; +import org.opencb.opencga.core.models.clinical.ClinicalAnalysis; import org.opencb.opencga.core.models.clinical.ExomiserWrapperParams; import org.opencb.opencga.core.models.common.mixins.GenericRecordAvroJsonMixin; import org.opencb.opencga.core.models.operations.variant.*; @@ -1017,6 +1018,7 @@ private void exomiser() throws Exception { ObjectMap params = new ExomiserWrapperParams( cliOptions.sample, + ClinicalAnalysis.Type.valueOf(cliOptions.clinicalAnalysisType), cliOptions.outdir) .toObjectMap(cliOptions.commonOptions.params).append(ParamConstants.STUDY_PARAM, cliOptions.study); diff --git a/opencga-app/src/main/java/org/opencb/opencga/app/cli/internal/options/VariantCommandOptions.java b/opencga-app/src/main/java/org/opencb/opencga/app/cli/internal/options/VariantCommandOptions.java index bad1beff087..daedb022e2c 100644 --- a/opencga-app/src/main/java/org/opencb/opencga/app/cli/internal/options/VariantCommandOptions.java +++ b/opencga-app/src/main/java/org/opencb/opencga/app/cli/internal/options/VariantCommandOptions.java @@ -48,6 +48,7 @@ import org.opencb.opencga.app.cli.internal.InternalCliOptionsParser; import org.opencb.opencga.core.api.FieldConstants; import org.opencb.opencga.core.api.ParamConstants; +import org.opencb.opencga.core.models.clinical.ClinicalAnalysis; import org.opencb.opencga.core.models.variant.AnnotationVariantQueryParams; import org.opencb.opencga.core.models.variant.SampleVariantFilterParams; import org.opencb.opencga.core.tools.variant.IndividualQcAnalysisExecutor; @@ -1844,6 +1845,9 @@ public class ExomiserAnalysisCommandOptions { @Parameter(names = {"--sample"}, description = "Sample ID.", required = true) public String sample; + @Parameter(names = {"--analysis-mode"}, description = "Analysis mode, valid values: SINGLE or FAMILY") + public String clinicalAnalysisType = ClinicalAnalysis.Type.SINGLE.name(); + @Parameter(names = {"-o", "--outdir"}, description = "Output directory.") public String outdir; } diff --git a/opencga-catalog/src/test/java/org/opencb/opencga/catalog/managers/AbstractClinicalManagerTest.java b/opencga-catalog/src/test/java/org/opencb/opencga/catalog/managers/AbstractClinicalManagerTest.java index 58b08381342..d9f384a5789 100644 --- a/opencga-catalog/src/test/java/org/opencb/opencga/catalog/managers/AbstractClinicalManagerTest.java +++ b/opencga-catalog/src/test/java/org/opencb/opencga/catalog/managers/AbstractClinicalManagerTest.java @@ -56,7 +56,8 @@ public class AbstractClinicalManagerTest extends GenericTest { public final static String PROBAND_ID2 = "manuel_individual"; public final static String CA_ID3 = "clinical-analysis-3"; - public final static String PROBAND_ID3 = "HG005_individual"; + + public final static String CA_ID4 = "clinical-analysis-4"; @Rule public ExpectedException thrown = ExpectedException.none(); @@ -127,7 +128,7 @@ public void setUpCatalogManager() throws IOException, CatalogException, URISynta catalogUploadFile("/biofiles/exomiser.vcf.gz"); //--------------------------------------------------------------------- - // Chinese trio (clinicalAnalysis3) + // Chinese trio: FAMILY (clinicalAnalysis3) //--------------------------------------------------------------------- Individual hg006Individual = new Individual().setId("HG006_individual") @@ -154,14 +155,14 @@ public void setUpCatalogManager() throws IOException, CatalogException, URISynta .setSex(SexOntologyTermAnnotation.initFemale()) .setSamples(Collections.singletonList(new Sample().setId("HG004"))); - Family chineseFamily = new Family("chinese_family", "chinese_family", null, null, + Family chineseFamily = new Family("chinese_trio_family", "chinese_trio_family", null, null, Arrays.asList(hg005Individual, hg006Individual, hg007Individual, hg004Individual), "", 4, Collections.emptyList(), Collections.emptyMap()); catalogManager.getFamilyManager().create(studyFqn, chineseFamily, QueryOptions.empty(), token).first(); auxClinicalAnalysis = new ClinicalAnalysis() .setId(CA_ID3) - .setDescription("My description - exomiser - trio") + .setDescription("My description - exomiser - trio - family") .setType(ClinicalAnalysis.Type.FAMILY) .setDueDate("20180510100000") .setDisorder(getDisorder()) @@ -175,6 +176,56 @@ public void setUpCatalogManager() throws IOException, CatalogException, URISynta catalogUploadFile("/biofiles/HG005.1k.vcf.gz"); catalogUploadFile("/biofiles/HG006.1k.vcf.gz"); catalogUploadFile("/biofiles/HG007.1k.vcf.gz"); + + //--------------------------------------------------------------------- + // Chinese trio: SINGLE (clinicalAnalysis4) + //--------------------------------------------------------------------- + + Individual hg106Individual = new Individual().setId("HG106_individual") + .setPhenotypes(Collections.emptyList()) + .setSex(SexOntologyTermAnnotation.initMale()) + .setSamples(Collections.singletonList(new Sample().setId("HG106"))); + + Individual hg107Individual = new Individual().setId("HG107_individual") + .setPhenotypes(Collections.emptyList()) + .setSex(SexOntologyTermAnnotation.initFemale()) + .setSamples(Collections.singletonList(new Sample().setId("HG107"))); + + Individual hg105Individual = new Individual().setId("HG105_individual") + .setDisorders(Collections.singletonList(getDisorder())) + .setPhenotypes(getPhenotypes()) + .setFather(hg106Individual) + .setMother(hg107Individual) + .setSex(SexOntologyTermAnnotation.initMale()) + .setSamples(Collections.singletonList(new Sample().setId("HG105"))); + + Individual hg104Individual = new Individual().setId("HG104_individual") + .setFather(hg106Individual) + .setMother(hg107Individual) + .setSex(SexOntologyTermAnnotation.initFemale()) + .setSamples(Collections.singletonList(new Sample().setId("HG104"))); + + Family chineseSingle = new Family("chinese_trio_single", "chinese_trio_single", null, null, + Arrays.asList(hg105Individual, hg106Individual, hg107Individual, hg104Individual), "", 4, Collections.emptyList(), + Collections.emptyMap()); + catalogManager.getFamilyManager().create(studyFqn, chineseSingle, QueryOptions.empty(), token).first(); + + auxClinicalAnalysis = new ClinicalAnalysis() + .setId(CA_ID4) + .setDescription("My description - exomiser - trio - single") + .setType(ClinicalAnalysis.Type.SINGLE) + .setDueDate("20180510100000") + .setDisorder(getDisorder()) + .setProband(hg105Individual) + .setFamily(chineseSingle); + + catalogManager.getClinicalAnalysisManager().create(studyFqn, auxClinicalAnalysis, QueryOptions.empty(), token) + .first(); + + catalogUploadFile("/biofiles/HG104.1k.vcf.gz"); + catalogUploadFile("/biofiles/HG105.1k.vcf.gz"); + catalogUploadFile("/biofiles/HG106.1k.vcf.gz"); + catalogUploadFile("/biofiles/HG107.1k.vcf.gz"); } private void catalogUploadFile(String path) throws IOException, CatalogException { diff --git a/opencga-catalog/src/test/resources/biofiles/HG104.1k.vcf.gz b/opencga-catalog/src/test/resources/biofiles/HG104.1k.vcf.gz new file mode 100644 index 0000000000000000000000000000000000000000..4237b056dfaf746b1d7dfa8606969d62d624a4e2 GIT binary patch literal 24986 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 literal 0 HcmV?d00001 diff --git a/opencga-catalog/src/test/resources/biofiles/HG105.1k.vcf.gz b/opencga-catalog/src/test/resources/biofiles/HG105.1k.vcf.gz new file mode 100644 index 0000000000000000000000000000000000000000..4bb5c469f015fb572582ac3eac06496022d8c240 GIT binary patch literal 27768 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 PtjPU8Cl^gm$&m*DOH->O literal 0 HcmV?d00001 diff --git a/opencga-catalog/src/test/resources/biofiles/HG106.1k.vcf.gz b/opencga-catalog/src/test/resources/biofiles/HG106.1k.vcf.gz new file mode 100644 index 0000000000000000000000000000000000000000..47cec223765fd3f095c6e3f9e07170a878c7decb GIT binary patch literal 24417 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 sGz+m93xIF}7`jeo@ literal 0 HcmV?d00001 diff --git a/opencga-catalog/src/test/resources/biofiles/HG107.1k.vcf.gz b/opencga-catalog/src/test/resources/biofiles/HG107.1k.vcf.gz new file mode 100644 index 0000000000000000000000000000000000000000..065f94379eacf4f3da378fd29105d5d24d90f774 GIT binary patch literal 24985 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 Date: Tue, 2 Apr 2024 17:51:21 +0200 Subject: [PATCH 16/85] tests: improve JUnit tests, #TASK-5603 --- .../ExomiserInterpretationAnalysis.java | 3 +- .../DockerWrapperAnalysisExecutor.java | 2 + .../ExomiserWrapperAnalysisExecutor.java | 4 +- .../clinical/ClinicalAnalysisUtilsTest.java | 4 ++ .../ExomiserInterpretationAnalysisTest.java | 62 ++++++++++++++++++- .../managers/AbstractClinicalManagerTest.java | 15 ++++- 6 files changed, 84 insertions(+), 6 deletions(-) diff --git a/opencga-analysis/src/main/java/org/opencb/opencga/analysis/clinical/exomiser/ExomiserInterpretationAnalysis.java b/opencga-analysis/src/main/java/org/opencb/opencga/analysis/clinical/exomiser/ExomiserInterpretationAnalysis.java index 0ae02104c82..5611d1c0d4f 100644 --- a/opencga-analysis/src/main/java/org/opencb/opencga/analysis/clinical/exomiser/ExomiserInterpretationAnalysis.java +++ b/opencga-analysis/src/main/java/org/opencb/opencga/analysis/clinical/exomiser/ExomiserInterpretationAnalysis.java @@ -191,7 +191,8 @@ private List getPrimaryFindings() throws IOException, StorageEn // Prepare variant query List sampleIds = new ArrayList<>(); - if (clinicalAnalysis.getFamily() != null && CollectionUtils.isNotEmpty(clinicalAnalysis.getFamily().getMembers())) { + if (clinicalAnalysis.getType() == ClinicalAnalysis.Type.FAMILY && clinicalAnalysis.getFamily() != null + && CollectionUtils.isNotEmpty(clinicalAnalysis.getFamily().getMembers())) { for (Individual member : clinicalAnalysis.getFamily().getMembers()) { Individual individual = IndividualQcUtils.getIndividualById(studyId, member.getId(), getCatalogManager(), getToken()); if (CollectionUtils.isNotEmpty(individual.getSamples())) { diff --git a/opencga-analysis/src/main/java/org/opencb/opencga/analysis/wrappers/executors/DockerWrapperAnalysisExecutor.java b/opencga-analysis/src/main/java/org/opencb/opencga/analysis/wrappers/executors/DockerWrapperAnalysisExecutor.java index ae2b5072473..d68f363b36d 100644 --- a/opencga-analysis/src/main/java/org/opencb/opencga/analysis/wrappers/executors/DockerWrapperAnalysisExecutor.java +++ b/opencga-analysis/src/main/java/org/opencb/opencga/analysis/wrappers/executors/DockerWrapperAnalysisExecutor.java @@ -31,6 +31,8 @@ public abstract class DockerWrapperAnalysisExecutor extends OpenCgaToolExecutor public static final String STDOUT_FILENAME = "stdout.txt"; public static final String STDERR_FILENAME = "stderr.txt"; + public static final String DOCKER_CLI_MSG = "Docker CLI: "; + public String getDockerImageName() { return "opencb/opencga-ext-tools"; } diff --git a/opencga-analysis/src/main/java/org/opencb/opencga/analysis/wrappers/exomiser/ExomiserWrapperAnalysisExecutor.java b/opencga-analysis/src/main/java/org/opencb/opencga/analysis/wrappers/exomiser/ExomiserWrapperAnalysisExecutor.java index cdbb24c2ab8..a6325932fb9 100644 --- a/opencga-analysis/src/main/java/org/opencb/opencga/analysis/wrappers/exomiser/ExomiserWrapperAnalysisExecutor.java +++ b/opencga-analysis/src/main/java/org/opencb/opencga/analysis/wrappers/exomiser/ExomiserWrapperAnalysisExecutor.java @@ -196,7 +196,9 @@ public void run() throws ToolException { .append(" --spring.config.location=/jobdir/").append(EXOMISER_PROPERTIES_TEMPLATE_FILENAME); // Execute command and redirect stdout and stderr to the files - logger.info("{}: Docker command line: {}", ID, sb); + String msg = DOCKER_CLI_MSG + sb; + logger.info(msg); + addWarning(msg); runCommandLine(sb.toString()); } diff --git a/opencga-analysis/src/test/java/org/opencb/opencga/analysis/clinical/ClinicalAnalysisUtilsTest.java b/opencga-analysis/src/test/java/org/opencb/opencga/analysis/clinical/ClinicalAnalysisUtilsTest.java index 26bf31c9dfc..f77a1025377 100644 --- a/opencga-analysis/src/test/java/org/opencb/opencga/analysis/clinical/ClinicalAnalysisUtilsTest.java +++ b/opencga-analysis/src/test/java/org/opencb/opencga/analysis/clinical/ClinicalAnalysisUtilsTest.java @@ -76,6 +76,10 @@ public static AbstractClinicalManagerTest getClinicalTest(OpenCGATestExternalRes variantStorageManager.index(clinicalTest.studyFqn, "HG005.1k.vcf.gz", outDir.toString(), storageOptions, clinicalTest.token); variantStorageManager.index(clinicalTest.studyFqn, "HG006.1k.vcf.gz", outDir.toString(), storageOptions, clinicalTest.token); variantStorageManager.index(clinicalTest.studyFqn, "HG007.1k.vcf.gz", outDir.toString(), storageOptions, clinicalTest.token); + variantStorageManager.index(clinicalTest.studyFqn, "HG104.1k.vcf.gz", outDir.toString(), storageOptions, clinicalTest.token); + variantStorageManager.index(clinicalTest.studyFqn, "HG105.1k.vcf.gz", outDir.toString(), storageOptions, clinicalTest.token); + variantStorageManager.index(clinicalTest.studyFqn, "HG106.1k.vcf.gz", outDir.toString(), storageOptions, clinicalTest.token); + variantStorageManager.index(clinicalTest.studyFqn, "HG107.1k.vcf.gz", outDir.toString(), storageOptions, clinicalTest.token); return clinicalTest; } diff --git a/opencga-analysis/src/test/java/org/opencb/opencga/analysis/clinical/exomiser/ExomiserInterpretationAnalysisTest.java b/opencga-analysis/src/test/java/org/opencb/opencga/analysis/clinical/exomiser/ExomiserInterpretationAnalysisTest.java index 04d8147529b..ba185297c28 100644 --- a/opencga-analysis/src/test/java/org/opencb/opencga/analysis/clinical/exomiser/ExomiserInterpretationAnalysisTest.java +++ b/opencga-analysis/src/test/java/org/opencb/opencga/analysis/clinical/exomiser/ExomiserInterpretationAnalysisTest.java @@ -1,19 +1,23 @@ package org.opencb.opencga.analysis.clinical.exomiser; +import org.apache.commons.lang3.StringUtils; import org.junit.After; import org.junit.BeforeClass; import org.junit.ClassRule; import org.junit.Test; +import org.opencb.biodata.models.clinical.interpretation.ClinicalVariant; import org.opencb.biodata.models.variant.Variant; import org.opencb.biodata.models.variant.exceptions.NonStandardCompliantSampleField; import org.opencb.biodata.tools.variant.VariantNormalizer; import org.junit.*; import org.eclipse.jetty.util.Scanner; import org.junit.experimental.categories.Category; +import org.opencb.commons.datastore.core.Event; import org.opencb.commons.datastore.core.ObjectMap; import org.opencb.commons.datastore.core.QueryOptions; import org.opencb.opencga.analysis.clinical.ClinicalAnalysisUtilsTest; import org.opencb.opencga.analysis.variant.OpenCGATestExternalResource; +import org.opencb.opencga.analysis.wrappers.executors.DockerWrapperAnalysisExecutor; import org.opencb.opencga.catalog.exceptions.CatalogException; import org.opencb.opencga.catalog.managers.AbstractClinicalManagerTest; import org.opencb.opencga.core.exceptions.ToolException; @@ -26,9 +30,13 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; +import java.util.Arrays; import java.util.Collections; +import java.util.List; import java.util.Optional; +import java.util.stream.Stream; +import static com.mongodb.assertions.Assertions.assertFalse; import static org.hamcrest.CoreMatchers.is; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; @@ -50,8 +58,8 @@ public static void setUp() throws Exception { clinicalTest = ClinicalAnalysisUtilsTest.getClinicalTest(opencga); } - @After - public void tearDown() throws Exception { + @AfterClass + public static void tearDown() throws Exception { opencga.clear(); } @@ -95,6 +103,22 @@ public void singleSingleExomiserAnalysis() throws IOException, CatalogException, .get(clinicalTest.studyFqn, clinicalTest.CA_ID2, QueryOptions.empty(), clinicalTest.token).first(); assertEquals(1, clinicalAnalysis.getSecondaryInterpretations().size()); assertTrue(clinicalAnalysis.getSecondaryInterpretations().get(0).getPrimaryFindings().size() > 0); + + // Check Exomiser docker CLI + boolean pedFound = false; + for (Event event : result.getEvents()) { + if (event.getType() == Event.Type.WARNING && StringUtils.isNotEmpty(event.getMessage()) + && event.getMessage().startsWith(DockerWrapperAnalysisExecutor.DOCKER_CLI_MSG)) { + List splits = Arrays.asList(event.getMessage().split(" ")); + pedFound = splits.contains("--ped") && splits.contains("/jobdir/" + clinicalTest.PROBAND_ID2 + ".ped"); + } + } + assertFalse(pedFound); + + // Only proband sample is returned in primary findings + for (ClinicalVariant cv : clinicalAnalysis.getInterpretation().getPrimaryFindings()) { + assertEquals(1, cv.getStudies().get(0).getSamples().size()); + } } @Test @@ -121,6 +145,23 @@ public void trioFamilyExomiserAnalysis() throws IOException, CatalogException, T .get(clinicalTest.studyFqn, clinicalTest.CA_ID3, QueryOptions.empty(), clinicalTest.token).first(); assertEquals(1, clinicalAnalysis.getSecondaryInterpretations().size()); assertTrue(clinicalAnalysis.getSecondaryInterpretations().get(0).getPrimaryFindings().size() > 0); + + // Check Exomiser docker CLI + boolean pedFound = false; + for (Event event : result.getEvents()) { + if (event.getType() == Event.Type.WARNING && StringUtils.isNotEmpty(event.getMessage()) + && event.getMessage().startsWith(DockerWrapperAnalysisExecutor.DOCKER_CLI_MSG)) { + List splits = Arrays.asList(event.getMessage().split(" ")); + pedFound = splits.contains("--ped") && splits.contains("/jobdir/" + clinicalTest.PROBAND_ID3 + ".ped"); + } + } + assertTrue(pedFound); + + // All family samples are returned in primary findings + for (ClinicalVariant cv : clinicalAnalysis.getInterpretation().getPrimaryFindings()) { + assertEquals(4, cv.getStudies().get(0).getSamples().size()); + } + System.out.println("results at out dir = " + outDir.toAbsolutePath()); } @@ -148,6 +189,23 @@ public void trioSingleExomiserAnalysis() throws IOException, CatalogException, T .get(clinicalTest.studyFqn, clinicalTest.CA_ID4, QueryOptions.empty(), clinicalTest.token).first(); assertEquals(1, clinicalAnalysis.getSecondaryInterpretations().size()); assertTrue(clinicalAnalysis.getSecondaryInterpretations().get(0).getPrimaryFindings().size() > 0); + + // Check Exomiser docker CLI + boolean pedFound = false; + for (Event event : result.getEvents()) { + if (event.getType() == Event.Type.WARNING && StringUtils.isNotEmpty(event.getMessage()) + && event.getMessage().startsWith(DockerWrapperAnalysisExecutor.DOCKER_CLI_MSG)) { + List splits = Arrays.asList(event.getMessage().split(" ")); + pedFound = splits.contains("--ped") && splits.contains("/jobdir/" + clinicalTest.PROBAND_ID4 + ".ped"); + } + } + assertFalse(pedFound); + + // Only proband sample is returned in primary findings + for (ClinicalVariant cv : clinicalAnalysis.getInterpretation().getPrimaryFindings()) { + assertEquals(1, cv.getStudies().get(0).getSamples().size()); + } + System.out.println("results at out dir = " + outDir.toAbsolutePath()); } diff --git a/opencga-catalog/src/test/java/org/opencb/opencga/catalog/managers/AbstractClinicalManagerTest.java b/opencga-catalog/src/test/java/org/opencb/opencga/catalog/managers/AbstractClinicalManagerTest.java index d9f384a5789..9a10ff857f1 100644 --- a/opencga-catalog/src/test/java/org/opencb/opencga/catalog/managers/AbstractClinicalManagerTest.java +++ b/opencga-catalog/src/test/java/org/opencb/opencga/catalog/managers/AbstractClinicalManagerTest.java @@ -16,6 +16,7 @@ package org.opencb.opencga.catalog.managers; +import org.junit.Assert; import org.junit.Before; import org.junit.Rule; import org.junit.experimental.categories.Category; @@ -23,6 +24,7 @@ import org.opencb.biodata.models.clinical.Disorder; import org.opencb.biodata.models.clinical.Phenotype; import org.opencb.biodata.models.core.SexOntologyTermAnnotation; +import org.opencb.commons.datastore.core.Query; import org.opencb.commons.datastore.core.QueryOptions; import org.opencb.commons.test.GenericTest; import org.opencb.opencga.catalog.exceptions.CatalogException; @@ -34,6 +36,7 @@ import org.opencb.opencga.core.models.sample.Sample; import org.opencb.opencga.core.models.study.Study; import org.opencb.opencga.core.models.user.Account; +import org.opencb.opencga.core.response.OpenCGAResult; import org.opencb.opencga.core.testclassification.duration.MediumTests; import java.io.IOException; @@ -45,6 +48,8 @@ import java.util.Collections; import java.util.List; +import static org.opencb.commons.datastore.core.QueryOptions.INCLUDE; + @Category(MediumTests.class) public class AbstractClinicalManagerTest extends GenericTest { @@ -56,8 +61,10 @@ public class AbstractClinicalManagerTest extends GenericTest { public final static String PROBAND_ID2 = "manuel_individual"; public final static String CA_ID3 = "clinical-analysis-3"; + public final static String PROBAND_ID3 = "HG005"; public final static String CA_ID4 = "clinical-analysis-4"; + public final static String PROBAND_ID4 = "HG105"; @Rule public ExpectedException thrown = ExpectedException.none(); @@ -147,7 +154,7 @@ public void setUpCatalogManager() throws IOException, CatalogException, URISynta .setFather(hg006Individual) .setMother(hg007Individual) .setSex(SexOntologyTermAnnotation.initMale()) - .setSamples(Collections.singletonList(new Sample().setId("HG005"))); + .setSamples(Collections.singletonList(new Sample().setId(PROBAND_ID3))); Individual hg004Individual = new Individual().setId("HG004_individual") .setFather(hg006Individual) @@ -197,7 +204,7 @@ public void setUpCatalogManager() throws IOException, CatalogException, URISynta .setFather(hg106Individual) .setMother(hg107Individual) .setSex(SexOntologyTermAnnotation.initMale()) - .setSamples(Collections.singletonList(new Sample().setId("HG105"))); + .setSamples(Collections.singletonList(new Sample().setId(PROBAND_ID4))); Individual hg104Individual = new Individual().setId("HG104_individual") .setFather(hg106Individual) @@ -226,6 +233,10 @@ public void setUpCatalogManager() throws IOException, CatalogException, URISynta catalogUploadFile("/biofiles/HG105.1k.vcf.gz"); catalogUploadFile("/biofiles/HG106.1k.vcf.gz"); catalogUploadFile("/biofiles/HG107.1k.vcf.gz"); + + + OpenCGAResult sampleResult = catalogManager.getSampleManager().search(studyFqn, new Query(), new QueryOptions(INCLUDE, "id"), token); + Assert.assertEquals(12, sampleResult.getNumResults()); } private void catalogUploadFile(String path) throws IOException, CatalogException { From dbd516fd6ce5d44e593f75d6a2d913b6ba6c505b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joaqu=C3=ADn=20T=C3=A1rraga=20Gim=C3=A9nez?= Date: Tue, 2 Apr 2024 18:13:13 +0200 Subject: [PATCH 17/85] app: fix Exomiser parameters, #TASK-5603 --- .../exomiser/ExomiserWrapperAnalysis.java | 3 ++- .../VariantInternalCommandExecutor.java | 2 +- .../internal/options/VariantCommandOptions.java | 6 +++--- .../opencb/opencga/core/api/FieldConstants.java | 6 +++--- .../models/clinical/ExomiserWrapperParams.java | 16 ++++++++++++---- 5 files changed, 21 insertions(+), 12 deletions(-) diff --git a/opencga-analysis/src/main/java/org/opencb/opencga/analysis/wrappers/exomiser/ExomiserWrapperAnalysis.java b/opencga-analysis/src/main/java/org/opencb/opencga/analysis/wrappers/exomiser/ExomiserWrapperAnalysis.java index 172f8629135..c4a9d87d4f7 100644 --- a/opencga-analysis/src/main/java/org/opencb/opencga/analysis/wrappers/exomiser/ExomiserWrapperAnalysis.java +++ b/opencga-analysis/src/main/java/org/opencb/opencga/analysis/wrappers/exomiser/ExomiserWrapperAnalysis.java @@ -19,6 +19,7 @@ import org.apache.commons.lang3.StringUtils; import org.opencb.opencga.analysis.tools.OpenCgaToolScopeStudy; import org.opencb.opencga.core.exceptions.ToolException; +import org.opencb.opencga.core.models.clinical.ClinicalAnalysis; import org.opencb.opencga.core.models.clinical.ExomiserWrapperParams; import org.opencb.opencga.core.models.common.Enums; import org.opencb.opencga.core.tools.annotations.Tool; @@ -52,7 +53,7 @@ protected void run() throws Exception { getToolExecutor(ExomiserWrapperAnalysisExecutor.class) .setStudyId(study) .setSampleId(analysisParams.getSample()) - .setSampleId(analysisParams.getSample()) + .setClinicalAnalysisType(ClinicalAnalysis.Type.valueOf(analysisParams.getClinicalAnalysisType())) .execute(); }); } diff --git a/opencga-app/src/main/java/org/opencb/opencga/app/cli/internal/executors/VariantInternalCommandExecutor.java b/opencga-app/src/main/java/org/opencb/opencga/app/cli/internal/executors/VariantInternalCommandExecutor.java index 34ee91a796e..b39a1387329 100644 --- a/opencga-app/src/main/java/org/opencb/opencga/app/cli/internal/executors/VariantInternalCommandExecutor.java +++ b/opencga-app/src/main/java/org/opencb/opencga/app/cli/internal/executors/VariantInternalCommandExecutor.java @@ -1018,7 +1018,7 @@ private void exomiser() throws Exception { ObjectMap params = new ExomiserWrapperParams( cliOptions.sample, - ClinicalAnalysis.Type.valueOf(cliOptions.clinicalAnalysisType), + cliOptions.clinicalAnalysisType, cliOptions.outdir) .toObjectMap(cliOptions.commonOptions.params).append(ParamConstants.STUDY_PARAM, cliOptions.study); diff --git a/opencga-app/src/main/java/org/opencb/opencga/app/cli/internal/options/VariantCommandOptions.java b/opencga-app/src/main/java/org/opencb/opencga/app/cli/internal/options/VariantCommandOptions.java index daedb022e2c..aa25fe630e1 100644 --- a/opencga-app/src/main/java/org/opencb/opencga/app/cli/internal/options/VariantCommandOptions.java +++ b/opencga-app/src/main/java/org/opencb/opencga/app/cli/internal/options/VariantCommandOptions.java @@ -1842,13 +1842,13 @@ public class ExomiserAnalysisCommandOptions { @Parameter(names = {"--study"}, description = "Study where all the samples belong to.") public String study; - @Parameter(names = {"--sample"}, description = "Sample ID.", required = true) + @Parameter(names = {"--sample"}, description = FieldConstants.SAMPLE_ID_DESCRIPTION, required = true) public String sample; - @Parameter(names = {"--analysis-mode"}, description = "Analysis mode, valid values: SINGLE or FAMILY") + @Parameter(names = {"--clinical-analysis-type"}, description = FieldConstants.EXOMISER_CLINICAL_ANALYSIS_TYPE_DESCRIPTION) public String clinicalAnalysisType = ClinicalAnalysis.Type.SINGLE.name(); - @Parameter(names = {"-o", "--outdir"}, description = "Output directory.") + @Parameter(names = {"-o", "--outdir"}, description = FieldConstants.JOB_OUT_DIR_DESCRIPTION) public String outdir; } } diff --git a/opencga-core/src/main/java/org/opencb/opencga/core/api/FieldConstants.java b/opencga-core/src/main/java/org/opencb/opencga/core/api/FieldConstants.java index d5476e10f60..2c2b3b9ee6a 100644 --- a/opencga-core/src/main/java/org/opencb/opencga/core/api/FieldConstants.java +++ b/opencga-core/src/main/java/org/opencb/opencga/core/api/FieldConstants.java @@ -38,9 +38,7 @@ public class FieldConstants { public static final String QUALITY_CONTROL_COMMENTS_DESCRIPTION = "Comments related to the quality control."; //Sample - public static final String SAMPLE_ID_DESCRIPTION = "Sample data model hosts information about any biological material, normally " - + "extracted from an _Individual_, that is used for a particular analysis. This is the main data model, it stores the most " - + "basic and important information."; + public static final String SAMPLE_ID_DESCRIPTION = "Sample ID."; public static final String SAMPLE_PROCESSING_DESCRIPTION = "Describes how the sample was processed in the lab."; public static final String SAMPLE_SAMPLE_COLLECTION_DESCRIPTION = "Describes how the sample was collected."; public static final String SAMPLE_QUALITY_CONTROL_DESCRIPTION = "Contains different metrics to evaluate the quality of the sample."; @@ -492,4 +490,6 @@ public class FieldConstants { + AlignmentQcParams.FASTQC_METRICS_SKIP_VALUE; public static final String ALIGNMENT_QC_OVERWRITE_DESCRIPTION = "To overwrite the QC metrics already computed."; + // Exomiser + public static final String EXOMISER_CLINICAL_ANALYSIS_TYPE_DESCRIPTION = "Clinical analysis type: SINGLE or FAMILY."; } diff --git a/opencga-core/src/main/java/org/opencb/opencga/core/models/clinical/ExomiserWrapperParams.java b/opencga-core/src/main/java/org/opencb/opencga/core/models/clinical/ExomiserWrapperParams.java index d2183090e14..3b836063439 100644 --- a/opencga-core/src/main/java/org/opencb/opencga/core/models/clinical/ExomiserWrapperParams.java +++ b/opencga-core/src/main/java/org/opencb/opencga/core/models/clinical/ExomiserWrapperParams.java @@ -1,5 +1,7 @@ package org.opencb.opencga.core.models.clinical; +import org.opencb.commons.annotations.DataField; +import org.opencb.opencga.core.api.FieldConstants; import org.opencb.opencga.core.tools.ToolParams; import java.util.Map; @@ -7,14 +9,20 @@ public class ExomiserWrapperParams extends ToolParams { public static final String DESCRIPTION = "Exomiser parameters"; + @DataField(id = "sample", description = FieldConstants.SAMPLE_ID_DESCRIPTION) private String sample; - private ClinicalAnalysis.Type clinicalAnalysisType; + + @DataField(id = "clinicalAnalysisType", description = FieldConstants.EXOMISER_CLINICAL_ANALYSIS_TYPE_DESCRIPTION, + defaultValue = "SINGLE") + private String clinicalAnalysisType; + + @DataField(id = "outdir", description = FieldConstants.JOB_OUT_DIR_DESCRIPTION) private String outdir; public ExomiserWrapperParams() { } - public ExomiserWrapperParams(String sample, ClinicalAnalysis.Type clinicalAnalysisType, String outdir) { + public ExomiserWrapperParams(String sample, String clinicalAnalysisType, String outdir) { this.sample = sample; this.clinicalAnalysisType = clinicalAnalysisType; this.outdir = outdir; @@ -39,11 +47,11 @@ public ExomiserWrapperParams setSample(String sample) { return this; } - public ClinicalAnalysis.Type getClinicalAnalysisType() { + public String getClinicalAnalysisType() { return clinicalAnalysisType; } - public ExomiserWrapperParams setClinicalAnalysisType(ClinicalAnalysis.Type clinicalAnalysisType) { + public ExomiserWrapperParams setClinicalAnalysisType(String clinicalAnalysisType) { this.clinicalAnalysisType = clinicalAnalysisType; return this; } From 339c0cf3aa273f452e20d6aa0acf210e9cfb7c96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joaqu=C3=ADn=20T=C3=A1rraga=20Gim=C3=A9nez?= Date: Tue, 2 Apr 2024 18:21:21 +0200 Subject: [PATCH 18/85] clients: generate clients, #TASK-5603 --- .../app/cli/main/OpenCgaCompleter.java | 2 +- .../app/cli/main/OpencgaCliOptionsParser.java | 2 +- .../AnalysisVariantCommandExecutor.java | 14 ++++++++++++- ...erationsVariantStorageCommandExecutor.java | 19 ++++++++++++------ .../executors/SamplesCommandExecutor.java | 1 + .../AnalysisVariantCommandOptions.java | 13 +++++++----- ...perationsVariantStorageCommandOptions.java | 16 +++++++-------- opencga-client/src/main/R/R/Admin-methods.R | 2 +- .../src/main/R/R/Alignment-methods.R | 2 +- opencga-client/src/main/R/R/AllGenerics.R | 20 +++++++++---------- .../src/main/R/R/Clinical-methods.R | 4 ++-- opencga-client/src/main/R/R/Cohort-methods.R | 4 ++-- opencga-client/src/main/R/R/Family-methods.R | 4 ++-- opencga-client/src/main/R/R/File-methods.R | 4 ++-- opencga-client/src/main/R/R/GA4GH-methods.R | 4 ++-- .../src/main/R/R/Individual-methods.R | 4 ++-- opencga-client/src/main/R/R/Job-methods.R | 4 ++-- opencga-client/src/main/R/R/Meta-methods.R | 2 +- .../src/main/R/R/Operation-methods.R | 2 +- opencga-client/src/main/R/R/Panel-methods.R | 2 +- opencga-client/src/main/R/R/Project-methods.R | 2 +- opencga-client/src/main/R/R/Sample-methods.R | 4 ++-- opencga-client/src/main/R/R/Study-methods.R | 4 ++-- opencga-client/src/main/R/R/User-methods.R | 4 ++-- opencga-client/src/main/R/R/Variant-methods.R | 2 +- .../client/rest/clients/AdminClient.java | 4 ++-- .../client/rest/clients/AlignmentClient.java | 4 ++-- .../rest/clients/ClinicalAnalysisClient.java | 4 ++-- .../client/rest/clients/CohortClient.java | 4 ++-- .../rest/clients/DiseasePanelClient.java | 4 ++-- .../client/rest/clients/FamilyClient.java | 4 ++-- .../client/rest/clients/FileClient.java | 4 ++-- .../client/rest/clients/GA4GHClient.java | 4 ++-- .../client/rest/clients/IndividualClient.java | 4 ++-- .../client/rest/clients/JobClient.java | 4 ++-- .../client/rest/clients/MetaClient.java | 4 ++-- .../client/rest/clients/ProjectClient.java | 4 ++-- .../client/rest/clients/SampleClient.java | 4 ++-- .../client/rest/clients/StudyClient.java | 4 ++-- .../client/rest/clients/UserClient.java | 4 ++-- .../client/rest/clients/VariantClient.java | 6 +++--- .../rest/clients/VariantOperationClient.java | 16 +++++++-------- opencga-client/src/main/javascript/Admin.js | 2 +- .../src/main/javascript/Alignment.js | 2 +- .../src/main/javascript/ClinicalAnalysis.js | 2 +- opencga-client/src/main/javascript/Cohort.js | 2 +- .../src/main/javascript/DiseasePanel.js | 2 +- opencga-client/src/main/javascript/Family.js | 2 +- opencga-client/src/main/javascript/File.js | 2 +- opencga-client/src/main/javascript/GA4GH.js | 2 +- .../src/main/javascript/Individual.js | 2 +- opencga-client/src/main/javascript/Job.js | 2 +- opencga-client/src/main/javascript/Meta.js | 2 +- opencga-client/src/main/javascript/Project.js | 2 +- opencga-client/src/main/javascript/Sample.js | 2 +- opencga-client/src/main/javascript/Study.js | 2 +- opencga-client/src/main/javascript/User.js | 2 +- opencga-client/src/main/javascript/Variant.js | 2 +- .../src/main/javascript/VariantOperation.js | 2 +- .../pyopencga/rest_clients/admin_client.py | 4 ++-- .../rest_clients/alignment_client.py | 4 ++-- .../rest_clients/clinical_analysis_client.py | 4 ++-- .../pyopencga/rest_clients/cohort_client.py | 4 ++-- .../rest_clients/disease_panel_client.py | 4 ++-- .../pyopencga/rest_clients/family_client.py | 4 ++-- .../pyopencga/rest_clients/file_client.py | 4 ++-- .../pyopencga/rest_clients/ga4gh_client.py | 4 ++-- .../rest_clients/individual_client.py | 4 ++-- .../pyopencga/rest_clients/job_client.py | 4 ++-- .../pyopencga/rest_clients/meta_client.py | 4 ++-- .../pyopencga/rest_clients/project_client.py | 4 ++-- .../pyopencga/rest_clients/sample_client.py | 4 ++-- .../pyopencga/rest_clients/study_client.py | 4 ++-- .../pyopencga/rest_clients/user_client.py | 4 ++-- .../pyopencga/rest_clients/variant_client.py | 4 ++-- .../rest_clients/variant_operation_client.py | 4 ++-- 76 files changed, 174 insertions(+), 151 deletions(-) diff --git a/opencga-app/src/main/java/org/opencb/opencga/app/cli/main/OpenCgaCompleter.java b/opencga-app/src/main/java/org/opencb/opencga/app/cli/main/OpenCgaCompleter.java index 48db1bde2fd..8aae8622858 100644 --- a/opencga-app/src/main/java/org/opencb/opencga/app/cli/main/OpenCgaCompleter.java +++ b/opencga-app/src/main/java/org/opencb/opencga/app/cli/main/OpenCgaCompleter.java @@ -1,5 +1,5 @@ /* -* Copyright 2015-2024-02-14 OpenCB +* Copyright 2015-2024-04-02 OpenCB * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/opencga-app/src/main/java/org/opencb/opencga/app/cli/main/OpencgaCliOptionsParser.java b/opencga-app/src/main/java/org/opencb/opencga/app/cli/main/OpencgaCliOptionsParser.java index af1660a9e33..39e19ee88e1 100644 --- a/opencga-app/src/main/java/org/opencb/opencga/app/cli/main/OpencgaCliOptionsParser.java +++ b/opencga-app/src/main/java/org/opencb/opencga/app/cli/main/OpencgaCliOptionsParser.java @@ -1,5 +1,5 @@ /* -* Copyright 2015-2024-02-14 OpenCB +* Copyright 2015-2024-04-02 OpenCB * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/opencga-app/src/main/java/org/opencb/opencga/app/cli/main/executors/AnalysisVariantCommandExecutor.java b/opencga-app/src/main/java/org/opencb/opencga/app/cli/main/executors/AnalysisVariantCommandExecutor.java index 59d5ba0c3db..de60333d151 100644 --- a/opencga-app/src/main/java/org/opencb/opencga/app/cli/main/executors/AnalysisVariantCommandExecutor.java +++ b/opencga-app/src/main/java/org/opencb/opencga/app/cli/main/executors/AnalysisVariantCommandExecutor.java @@ -1,9 +1,16 @@ package org.opencb.opencga.app.cli.main.executors; import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import org.opencb.biodata.models.clinical.ClinicalProperty.ModeOfInheritance; +import org.opencb.biodata.models.clinical.ClinicalProperty.Penetrance; import org.opencb.biodata.models.clinical.qc.Signature; import org.opencb.biodata.models.variant.Variant; import org.opencb.biodata.models.variant.avro.VariantAnnotation; +import org.opencb.biodata.models.variant.metadata.Aggregation; import org.opencb.biodata.models.variant.metadata.SampleVariantStats; import org.opencb.biodata.models.variant.metadata.VariantMetadata; import org.opencb.biodata.models.variant.metadata.VariantSetStats; @@ -12,14 +19,18 @@ import org.opencb.commons.datastore.core.QueryResponse; import org.opencb.commons.utils.PrintUtils; import org.opencb.opencga.app.cli.main.*; +import org.opencb.opencga.app.cli.main.executors.OpencgaCommandExecutor; import org.opencb.opencga.app.cli.main.options.AnalysisVariantCommandOptions; import org.opencb.opencga.catalog.exceptions.CatalogAuthenticationException; +import org.opencb.opencga.client.exceptions.ClientException; import org.opencb.opencga.core.common.JacksonUtils; import org.opencb.opencga.core.models.analysis.knockout.KnockoutByGene; import org.opencb.opencga.core.models.analysis.knockout.KnockoutByIndividual; import org.opencb.opencga.core.models.clinical.ExomiserWrapperParams; import org.opencb.opencga.core.models.job.Job; +import org.opencb.opencga.core.models.operations.variant.VariantIndexParams; import org.opencb.opencga.core.models.operations.variant.VariantStatsExportParams; +import org.opencb.opencga.core.models.variant.AnnotationVariantQueryParams; import org.opencb.opencga.core.models.variant.CircosAnalysisParams; import org.opencb.opencga.core.models.variant.CohortVariantStatsAnalysisParams; import org.opencb.opencga.core.models.variant.FamilyQcAnalysisParams; @@ -40,10 +51,10 @@ import org.opencb.opencga.core.models.variant.SampleVariantFilterParams; import org.opencb.opencga.core.models.variant.SampleVariantStatsAnalysisParams; import org.opencb.opencga.core.models.variant.VariantExportParams; -import org.opencb.opencga.core.models.operations.variant.VariantIndexParams; import org.opencb.opencga.core.models.variant.VariantStatsAnalysisParams; import org.opencb.opencga.core.response.QueryType; import org.opencb.opencga.core.response.RestResponse; +import org.opencb.oskar.analysis.variant.gwas.GwasConfiguration; /* @@ -416,6 +427,7 @@ private RestResponse runExomiser() throws Exception { } else { ObjectMap beanParams = new ObjectMap(); putNestedIfNotEmpty(beanParams, "sample",commandOptions.sample, true); + putNestedIfNotEmpty(beanParams, "clinicalAnalysisType",commandOptions.clinicalAnalysisType, true); putNestedIfNotEmpty(beanParams, "outdir",commandOptions.outdir, true); exomiserWrapperParams = JacksonUtils.getDefaultObjectMapper().copy() diff --git a/opencga-app/src/main/java/org/opencb/opencga/app/cli/main/executors/OperationsVariantStorageCommandExecutor.java b/opencga-app/src/main/java/org/opencb/opencga/app/cli/main/executors/OperationsVariantStorageCommandExecutor.java index 294763c0b74..0b3a28d11b3 100644 --- a/opencga-app/src/main/java/org/opencb/opencga/app/cli/main/executors/OperationsVariantStorageCommandExecutor.java +++ b/opencga-app/src/main/java/org/opencb/opencga/app/cli/main/executors/OperationsVariantStorageCommandExecutor.java @@ -1,12 +1,19 @@ package org.opencb.opencga.app.cli.main.executors; import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import java.util.HashMap; +import java.util.List; +import org.opencb.biodata.models.variant.metadata.Aggregation; import org.opencb.commons.datastore.core.ObjectMap; import org.opencb.commons.utils.PrintUtils; import org.opencb.opencga.app.cli.main.*; +import org.opencb.opencga.app.cli.main.executors.OpencgaCommandExecutor; import org.opencb.opencga.app.cli.main.options.OperationsVariantStorageCommandOptions; import org.opencb.opencga.catalog.exceptions.CatalogAuthenticationException; +import org.opencb.opencga.client.exceptions.ClientException; import org.opencb.opencga.core.common.JacksonUtils; +import org.opencb.opencga.core.common.YesNoAuto; import org.opencb.opencga.core.config.storage.CellBaseConfiguration; import org.opencb.opencga.core.config.storage.SampleIndexConfiguration; import org.opencb.opencga.core.models.job.Job; @@ -15,19 +22,19 @@ import org.opencb.opencga.core.models.operations.variant.VariantAggregateParams; import org.opencb.opencga.core.models.operations.variant.VariantAnnotationIndexParams; import org.opencb.opencga.core.models.operations.variant.VariantAnnotationSaveParams; +import org.opencb.opencga.core.models.operations.variant.VariantConfigureParams; import org.opencb.opencga.core.models.operations.variant.VariantFamilyIndexParams; +import org.opencb.opencga.core.models.operations.variant.VariantFileDeleteParams; +import org.opencb.opencga.core.models.operations.variant.VariantFileIndexJobLauncherParams; +import org.opencb.opencga.core.models.operations.variant.VariantIndexParams; +import org.opencb.opencga.core.models.operations.variant.VariantPruneParams; +import org.opencb.opencga.core.models.operations.variant.VariantSampleDeleteParams; import org.opencb.opencga.core.models.operations.variant.VariantScoreIndexParams; import org.opencb.opencga.core.models.operations.variant.VariantSecondaryAnnotationIndexParams; import org.opencb.opencga.core.models.operations.variant.VariantSecondarySampleIndexParams; import org.opencb.opencga.core.models.operations.variant.VariantStatsDeleteParams; import org.opencb.opencga.core.models.operations.variant.VariantStatsIndexParams; import org.opencb.opencga.core.models.operations.variant.VariantStorageMetadataRepairToolParams; -import org.opencb.opencga.core.models.operations.variant.VariantConfigureParams; -import org.opencb.opencga.core.models.operations.variant.VariantFileDeleteParams; -import org.opencb.opencga.core.models.operations.variant.VariantFileIndexJobLauncherParams; -import org.opencb.opencga.core.models.operations.variant.VariantIndexParams; -import org.opencb.opencga.core.models.operations.variant.VariantPruneParams; -import org.opencb.opencga.core.models.operations.variant.VariantSampleDeleteParams; import org.opencb.opencga.core.models.operations.variant.VariantStorageMetadataSynchronizeParams; import org.opencb.opencga.core.models.operations.variant.VariantStudyDeleteParams; import org.opencb.opencga.core.response.QueryType; diff --git a/opencga-app/src/main/java/org/opencb/opencga/app/cli/main/executors/SamplesCommandExecutor.java b/opencga-app/src/main/java/org/opencb/opencga/app/cli/main/executors/SamplesCommandExecutor.java index 7ed949a68a5..328cc9eb556 100644 --- a/opencga-app/src/main/java/org/opencb/opencga/app/cli/main/executors/SamplesCommandExecutor.java +++ b/opencga-app/src/main/java/org/opencb/opencga/app/cli/main/executors/SamplesCommandExecutor.java @@ -125,6 +125,7 @@ private RestResponse updateAcl() throws Exception { queryParams.putIfNotEmpty("study", sessionManager.getSession().getCurrentStudy()); } + SampleAclUpdateParams sampleAclUpdateParams = null; if (commandOptions.jsonDataModel) { RestResponse res = new RestResponse<>(); diff --git a/opencga-app/src/main/java/org/opencb/opencga/app/cli/main/options/AnalysisVariantCommandOptions.java b/opencga-app/src/main/java/org/opencb/opencga/app/cli/main/options/AnalysisVariantCommandOptions.java index ed53b2c1ded..f4a675b0e53 100644 --- a/opencga-app/src/main/java/org/opencb/opencga/app/cli/main/options/AnalysisVariantCommandOptions.java +++ b/opencga-app/src/main/java/org/opencb/opencga/app/cli/main/options/AnalysisVariantCommandOptions.java @@ -410,10 +410,13 @@ public class RunExomiserCommandOptions { @Parameter(names = {"--job-tags"}, description = "Job tags", required = false, arity = 1) public String jobTags; - @Parameter(names = {"--sample"}, description = "The body web service sample parameter", required = false, arity = 1) + @Parameter(names = {"--sample"}, description = "Sample ID.", required = false, arity = 1) public String sample; - @Parameter(names = {"--outdir"}, description = "The body web service outdir parameter", required = false, arity = 1) + @Parameter(names = {"--clinical-analysis-type"}, description = "Clinical analysis type: SINGLE or FAMILY.", required = false, arity = 1) + public String clinicalAnalysisType = "SINGLE"; + + @Parameter(names = {"--outdir"}, description = "Output dir for the job.", required = false, arity = 1) public String outdir; } @@ -993,7 +996,7 @@ public class RunHrDetectCommandOptions { @Parameter(names = {"--description"}, description = "Decription for these particular HRDetect results.", required = false, arity = 1) public String description; - @Parameter(names = {"--sample-id"}, description = "Sample data model hosts information about any biological material, normally extracted from an _Individual_, that is used for a particular analysis. This is the main data model, it stores the most basic and important information.", required = false, arity = 1) + @Parameter(names = {"--sample-id"}, description = "Sample ID.", required = false, arity = 1) public String sampleId; @Parameter(names = {"--snv-fitting-id"}, description = "Mutational signature fitting ID for SNV.", required = false, arity = 1) @@ -1079,7 +1082,7 @@ public class RunIndexCommandOptions { @Parameter(names = {"--fail-on-malformed-lines"}, description = "Fail when encountering malformed lines. (yes, no, auto) [auto]", required = false, arity = 1) public String failOnMalformedLines; - @Parameter(names = {"--family"}, description = "Indicate that the files to be loaded are part of a family. This will set 'load-hom-ref' to YES if it was in AUTO and execute 'family-index' afterwards", required = false, help = true, arity = 0) + @Parameter(names = {"--family"}, description = "Indicate that the files to be loaded are part of a family. This will set 'load-hom-ref' to YES if it was in AUTO", required = false, help = true, arity = 0) public boolean family = false; @Parameter(names = {"--somatic"}, description = "Indicate that the files to be loaded contain somatic samples. This will set 'load-hom-ref' to YES if it was in AUTO.", required = false, help = true, arity = 0) @@ -2035,7 +2038,7 @@ public class RunSampleQcCommandOptions { @Parameter(names = {"--job-tags"}, description = "Job tags", required = false, arity = 1) public String jobTags; - @Parameter(names = {"--sample"}, description = "Sample data model hosts information about any biological material, normally extracted from an _Individual_, that is used for a particular analysis. This is the main data model, it stores the most basic and important information.", required = false, arity = 1) + @Parameter(names = {"--sample"}, description = "Sample ID.", required = false, arity = 1) public String sample; @Parameter(names = {"--vs-id"}, description = "Variant stats ID.", required = false, arity = 1) diff --git a/opencga-app/src/main/java/org/opencb/opencga/app/cli/main/options/OperationsVariantStorageCommandOptions.java b/opencga-app/src/main/java/org/opencb/opencga/app/cli/main/options/OperationsVariantStorageCommandOptions.java index a9b95be294a..4f81b547328 100644 --- a/opencga-app/src/main/java/org/opencb/opencga/app/cli/main/options/OperationsVariantStorageCommandOptions.java +++ b/opencga-app/src/main/java/org/opencb/opencga/app/cli/main/options/OperationsVariantStorageCommandOptions.java @@ -160,10 +160,10 @@ public class AggregateVariantCommandOptions { @Parameter(names = {"--study", "-s"}, description = "Study [[user@]project:]study where study and project can be either the ID or UUID", required = false, arity = 1) public String study; - @Parameter(names = {"--overwrite"}, description = "The body web service overwrite parameter", required = false, help = true, arity = 0) + @Parameter(names = {"--overwrite"}, description = "Overwrite aggregation for all files and variants. Repeat operation for already processed variants.", required = false, help = true, arity = 0) public boolean overwrite = false; - @Parameter(names = {"--resume"}, description = "The body web service resume parameter", required = false, help = true, arity = 0) + @Parameter(names = {"--resume"}, description = "Resume a previously failed index operation", required = false, help = true, arity = 0) public boolean resume = false; } @@ -280,7 +280,7 @@ public class SaveVariantAnnotationCommandOptions { @Parameter(names = {"--project", "-p"}, description = "Project [user@]project where project can be either the ID or the alias", required = false, arity = 1) public String project; - @Parameter(names = {"--annotation-id"}, description = "The body web service annotationId parameter", required = false, arity = 1) + @Parameter(names = {"--annotation-id"}, description = "New Variant Annotation identifier", required = false, arity = 1) public String annotationId; } @@ -370,13 +370,13 @@ public class AggregateVariantFamilyCommandOptions { @Parameter(names = {"--study", "-s"}, description = "Study [[user@]project:]study where study and project can be either the ID or UUID", required = false, arity = 1) public String study; - @Parameter(names = {"--samples"}, description = "The body web service samples parameter", required = false, arity = 1) + @Parameter(names = {"--samples"}, description = "Samples within the same study to aggregate", required = false, arity = 1) public String samples; - @Parameter(names = {"--gaps-genotype"}, description = "The body web service gapsGenotype parameter", required = false, arity = 1) + @Parameter(names = {"--gaps-genotype"}, description = "Genotype to be used in gaps. Either 0/0, ./. or ?/?", required = false, arity = 1) public String gapsGenotype; - @Parameter(names = {"--resume"}, description = "The body web service resume parameter", required = false, help = true, arity = 0) + @Parameter(names = {"--resume"}, description = "Resume a previously failed index operation", required = false, help = true, arity = 0) public boolean resume = false; } @@ -473,7 +473,7 @@ public class IndexVariantCommandOptions { @Parameter(names = {"--fail-on-malformed-lines"}, description = "Fail when encountering malformed lines. (yes, no, auto) [auto]", required = false, arity = 1) public String failOnMalformedLines; - @Parameter(names = {"--family"}, description = "Indicate that the files to be loaded are part of a family. This will set 'load-hom-ref' to YES if it was in AUTO and execute 'family-index' afterwards", required = false, help = true, arity = 0) + @Parameter(names = {"--family"}, description = "Indicate that the files to be loaded are part of a family. This will set 'load-hom-ref' to YES if it was in AUTO", required = false, help = true, arity = 0) public boolean family = false; @Parameter(names = {"--somatic"}, description = "Indicate that the files to be loaded contain somatic samples. This will set 'load-hom-ref' to YES if it was in AUTO.", required = false, help = true, arity = 0) @@ -607,7 +607,7 @@ public class LauncherVariantIndexCommandOptions { @Parameter(names = {"--index-params-fail-on-malformed-lines"}, description = "Fail when encountering malformed lines. (yes, no, auto) [auto]", required = false, arity = 1) public String indexParamsFailOnMalformedLines; - @Parameter(names = {"--index-params-family"}, description = "Indicate that the files to be loaded are part of a family. This will set 'load-hom-ref' to YES if it was in AUTO and execute 'family-index' afterwards", required = false, help = true, arity = 0) + @Parameter(names = {"--index-params-family"}, description = "Indicate that the files to be loaded are part of a family. This will set 'load-hom-ref' to YES if it was in AUTO", required = false, help = true, arity = 0) public boolean indexParamsFamily = false; @Parameter(names = {"--index-params-somatic"}, description = "Indicate that the files to be loaded contain somatic samples. This will set 'load-hom-ref' to YES if it was in AUTO.", required = false, help = true, arity = 0) diff --git a/opencga-client/src/main/R/R/Admin-methods.R b/opencga-client/src/main/R/R/Admin-methods.R index c3041969f51..9eb3da76a50 100644 --- a/opencga-client/src/main/R/R/Admin-methods.R +++ b/opencga-client/src/main/R/R/Admin-methods.R @@ -2,7 +2,7 @@ # WARNING: AUTOGENERATED CODE # # This code was generated by a tool. -# Autogenerated on: 2024-02-14 +# Autogenerated on: 2024-04-02 # # Manual changes to this file may cause unexpected behavior in your application. # Manual changes to this file will be overwritten if the code is regenerated. diff --git a/opencga-client/src/main/R/R/Alignment-methods.R b/opencga-client/src/main/R/R/Alignment-methods.R index 53cd5d9802c..f2305dc2afc 100644 --- a/opencga-client/src/main/R/R/Alignment-methods.R +++ b/opencga-client/src/main/R/R/Alignment-methods.R @@ -2,7 +2,7 @@ # WARNING: AUTOGENERATED CODE # # This code was generated by a tool. -# Autogenerated on: 2024-02-14 +# Autogenerated on: 2024-04-02 # # Manual changes to this file may cause unexpected behavior in your application. # Manual changes to this file will be overwritten if the code is regenerated. diff --git a/opencga-client/src/main/R/R/AllGenerics.R b/opencga-client/src/main/R/R/AllGenerics.R index f9fdb51fe6f..b95464800e9 100644 --- a/opencga-client/src/main/R/R/AllGenerics.R +++ b/opencga-client/src/main/R/R/AllGenerics.R @@ -1,6 +1,6 @@ # ############################################################################## ## UserClient -setGeneric("userClient", function(OpencgaR, user, users, filterId, endpointName, params=NULL, ...) +setGeneric("userClient", function(OpencgaR, filterId, users, user, endpointName, params=NULL, ...) standardGeneric("userClient")) # ############################################################################## @@ -10,37 +10,37 @@ setGeneric("projectClient", function(OpencgaR, project, projects, endpointName, # ############################################################################## ## StudyClient -setGeneric("studyClient", function(OpencgaR, group, variableSet, studies, templateId, study, members, endpointName, params=NULL, ...) +setGeneric("studyClient", function(OpencgaR, study, group, studies, members, templateId, variableSet, endpointName, params=NULL, ...) standardGeneric("studyClient")) # ############################################################################## ## FileClient -setGeneric("fileClient", function(OpencgaR, folder, annotationSet, file, files, members, endpointName, params=NULL, ...) +setGeneric("fileClient", function(OpencgaR, file, annotationSet, members, folder, files, endpointName, params=NULL, ...) standardGeneric("fileClient")) # ############################################################################## ## JobClient -setGeneric("jobClient", function(OpencgaR, job, members, jobs, endpointName, params=NULL, ...) +setGeneric("jobClient", function(OpencgaR, members, job, jobs, endpointName, params=NULL, ...) standardGeneric("jobClient")) # ############################################################################## ## SampleClient -setGeneric("sampleClient", function(OpencgaR, samples, annotationSet, members, sample, endpointName, params=NULL, ...) +setGeneric("sampleClient", function(OpencgaR, annotationSet, members, sample, samples, endpointName, params=NULL, ...) standardGeneric("sampleClient")) # ############################################################################## ## IndividualClient -setGeneric("individualClient", function(OpencgaR, individuals, members, annotationSet, individual, endpointName, params=NULL, ...) +setGeneric("individualClient", function(OpencgaR, annotationSet, members, individual, individuals, endpointName, params=NULL, ...) standardGeneric("individualClient")) # ############################################################################## ## FamilyClient -setGeneric("familyClient", function(OpencgaR, families, family, members, annotationSet, endpointName, params=NULL, ...) +setGeneric("familyClient", function(OpencgaR, annotationSet, family, members, families, endpointName, params=NULL, ...) standardGeneric("familyClient")) # ############################################################################## ## CohortClient -setGeneric("cohortClient", function(OpencgaR, cohort, members, annotationSet, cohorts, endpointName, params=NULL, ...) +setGeneric("cohortClient", function(OpencgaR, annotationSet, members, cohort, cohorts, endpointName, params=NULL, ...) standardGeneric("cohortClient")) # ############################################################################## @@ -60,7 +60,7 @@ setGeneric("variantClient", function(OpencgaR, endpointName, params=NULL, ...) # ############################################################################## ## ClinicalClient -setGeneric("clinicalClient", function(OpencgaR, interpretation, clinicalAnalysis, interpretations, annotationSet, clinicalAnalyses, members, endpointName, params=NULL, ...) +setGeneric("clinicalClient", function(OpencgaR, interpretations, clinicalAnalyses, annotationSet, members, clinicalAnalysis, interpretation, endpointName, params=NULL, ...) standardGeneric("clinicalClient")) # ############################################################################## @@ -75,7 +75,7 @@ setGeneric("metaClient", function(OpencgaR, endpointName, params=NULL, ...) # ############################################################################## ## GA4GHClient -setGeneric("ga4ghClient", function(OpencgaR, study, file, endpointName, params=NULL, ...) +setGeneric("ga4ghClient", function(OpencgaR, file, study, endpointName, params=NULL, ...) standardGeneric("ga4ghClient")) # ############################################################################## diff --git a/opencga-client/src/main/R/R/Clinical-methods.R b/opencga-client/src/main/R/R/Clinical-methods.R index ecd04d6d74d..12050747f04 100644 --- a/opencga-client/src/main/R/R/Clinical-methods.R +++ b/opencga-client/src/main/R/R/Clinical-methods.R @@ -2,7 +2,7 @@ # WARNING: AUTOGENERATED CODE # # This code was generated by a tool. -# Autogenerated on: 2024-02-14 +# Autogenerated on: 2024-04-02 # # Manual changes to this file may cause unexpected behavior in your application. # Manual changes to this file will be overwritten if the code is regenerated. @@ -61,7 +61,7 @@ #' [*]: Required parameter #' @export -setMethod("clinicalClient", "OpencgaR", function(OpencgaR, interpretation, clinicalAnalysis, interpretations, annotationSet, clinicalAnalyses, members, endpointName, params=NULL, ...) { +setMethod("clinicalClient", "OpencgaR", function(OpencgaR, interpretations, clinicalAnalyses, annotationSet, members, clinicalAnalysis, interpretation, endpointName, params=NULL, ...) { switch(endpointName, #' @section Endpoint /{apiVersion}/analysis/clinical/acl/{members}/update: diff --git a/opencga-client/src/main/R/R/Cohort-methods.R b/opencga-client/src/main/R/R/Cohort-methods.R index b4cbb071860..0f06995005e 100644 --- a/opencga-client/src/main/R/R/Cohort-methods.R +++ b/opencga-client/src/main/R/R/Cohort-methods.R @@ -2,7 +2,7 @@ # WARNING: AUTOGENERATED CODE # # This code was generated by a tool. -# Autogenerated on: 2024-02-14 +# Autogenerated on: 2024-04-02 # # Manual changes to this file may cause unexpected behavior in your application. # Manual changes to this file will be overwritten if the code is regenerated. @@ -39,7 +39,7 @@ #' [*]: Required parameter #' @export -setMethod("cohortClient", "OpencgaR", function(OpencgaR, cohort, members, annotationSet, cohorts, endpointName, params=NULL, ...) { +setMethod("cohortClient", "OpencgaR", function(OpencgaR, annotationSet, members, cohort, cohorts, endpointName, params=NULL, ...) { switch(endpointName, #' @section Endpoint /{apiVersion}/cohorts/acl/{members}/update: diff --git a/opencga-client/src/main/R/R/Family-methods.R b/opencga-client/src/main/R/R/Family-methods.R index 9f965314e0f..ae6fcf23567 100644 --- a/opencga-client/src/main/R/R/Family-methods.R +++ b/opencga-client/src/main/R/R/Family-methods.R @@ -2,7 +2,7 @@ # WARNING: AUTOGENERATED CODE # # This code was generated by a tool. -# Autogenerated on: 2024-02-14 +# Autogenerated on: 2024-04-02 # # Manual changes to this file may cause unexpected behavior in your application. # Manual changes to this file will be overwritten if the code is regenerated. @@ -38,7 +38,7 @@ #' [*]: Required parameter #' @export -setMethod("familyClient", "OpencgaR", function(OpencgaR, families, family, members, annotationSet, endpointName, params=NULL, ...) { +setMethod("familyClient", "OpencgaR", function(OpencgaR, annotationSet, family, members, families, endpointName, params=NULL, ...) { switch(endpointName, #' @section Endpoint /{apiVersion}/families/acl/{members}/update: diff --git a/opencga-client/src/main/R/R/File-methods.R b/opencga-client/src/main/R/R/File-methods.R index fd0ad7f691c..11e4a3b6e53 100644 --- a/opencga-client/src/main/R/R/File-methods.R +++ b/opencga-client/src/main/R/R/File-methods.R @@ -2,7 +2,7 @@ # WARNING: AUTOGENERATED CODE # # This code was generated by a tool. -# Autogenerated on: 2024-02-14 +# Autogenerated on: 2024-04-02 # # Manual changes to this file may cause unexpected behavior in your application. # Manual changes to this file will be overwritten if the code is regenerated. @@ -54,7 +54,7 @@ #' [*]: Required parameter #' @export -setMethod("fileClient", "OpencgaR", function(OpencgaR, folder, annotationSet, file, files, members, endpointName, params=NULL, ...) { +setMethod("fileClient", "OpencgaR", function(OpencgaR, file, annotationSet, members, folder, files, endpointName, params=NULL, ...) { switch(endpointName, #' @section Endpoint /{apiVersion}/files/acl/{members}/update: diff --git a/opencga-client/src/main/R/R/GA4GH-methods.R b/opencga-client/src/main/R/R/GA4GH-methods.R index d9d2c5689e4..66438d21bf7 100644 --- a/opencga-client/src/main/R/R/GA4GH-methods.R +++ b/opencga-client/src/main/R/R/GA4GH-methods.R @@ -2,7 +2,7 @@ # WARNING: AUTOGENERATED CODE # # This code was generated by a tool. -# Autogenerated on: 2024-02-14 +# Autogenerated on: 2024-04-02 # # Manual changes to this file may cause unexpected behavior in your application. # Manual changes to this file will be overwritten if the code is regenerated. @@ -31,7 +31,7 @@ #' [*]: Required parameter #' @export -setMethod("ga4ghClient", "OpencgaR", function(OpencgaR, study, file, endpointName, params=NULL, ...) { +setMethod("ga4ghClient", "OpencgaR", function(OpencgaR, file, study, endpointName, params=NULL, ...) { switch(endpointName, #' @section Endpoint /{apiVersion}/ga4gh/reads/search: diff --git a/opencga-client/src/main/R/R/Individual-methods.R b/opencga-client/src/main/R/R/Individual-methods.R index 72d5e0839dc..eec88910643 100644 --- a/opencga-client/src/main/R/R/Individual-methods.R +++ b/opencga-client/src/main/R/R/Individual-methods.R @@ -2,7 +2,7 @@ # WARNING: AUTOGENERATED CODE # # This code was generated by a tool. -# Autogenerated on: 2024-02-14 +# Autogenerated on: 2024-04-02 # # Manual changes to this file may cause unexpected behavior in your application. # Manual changes to this file will be overwritten if the code is regenerated. @@ -39,7 +39,7 @@ #' [*]: Required parameter #' @export -setMethod("individualClient", "OpencgaR", function(OpencgaR, individuals, members, annotationSet, individual, endpointName, params=NULL, ...) { +setMethod("individualClient", "OpencgaR", function(OpencgaR, annotationSet, members, individual, individuals, endpointName, params=NULL, ...) { switch(endpointName, #' @section Endpoint /{apiVersion}/individuals/acl/{members}/update: diff --git a/opencga-client/src/main/R/R/Job-methods.R b/opencga-client/src/main/R/R/Job-methods.R index edfb52fbaff..37c35708bab 100644 --- a/opencga-client/src/main/R/R/Job-methods.R +++ b/opencga-client/src/main/R/R/Job-methods.R @@ -2,7 +2,7 @@ # WARNING: AUTOGENERATED CODE # # This code was generated by a tool. -# Autogenerated on: 2024-02-14 +# Autogenerated on: 2024-04-02 # # Manual changes to this file may cause unexpected behavior in your application. # Manual changes to this file will be overwritten if the code is regenerated. @@ -40,7 +40,7 @@ #' [*]: Required parameter #' @export -setMethod("jobClient", "OpencgaR", function(OpencgaR, job, members, jobs, endpointName, params=NULL, ...) { +setMethod("jobClient", "OpencgaR", function(OpencgaR, members, job, jobs, endpointName, params=NULL, ...) { switch(endpointName, #' @section Endpoint /{apiVersion}/jobs/acl/{members}/update: diff --git a/opencga-client/src/main/R/R/Meta-methods.R b/opencga-client/src/main/R/R/Meta-methods.R index 730500d7b4a..4281a8dd7a0 100644 --- a/opencga-client/src/main/R/R/Meta-methods.R +++ b/opencga-client/src/main/R/R/Meta-methods.R @@ -2,7 +2,7 @@ # WARNING: AUTOGENERATED CODE # # This code was generated by a tool. -# Autogenerated on: 2024-02-14 +# Autogenerated on: 2024-04-02 # # Manual changes to this file may cause unexpected behavior in your application. # Manual changes to this file will be overwritten if the code is regenerated. diff --git a/opencga-client/src/main/R/R/Operation-methods.R b/opencga-client/src/main/R/R/Operation-methods.R index 11e89656de2..20688eb888d 100644 --- a/opencga-client/src/main/R/R/Operation-methods.R +++ b/opencga-client/src/main/R/R/Operation-methods.R @@ -2,7 +2,7 @@ # WARNING: AUTOGENERATED CODE # # This code was generated by a tool. -# Autogenerated on: 2024-02-14 +# Autogenerated on: 2024-04-02 # # Manual changes to this file may cause unexpected behavior in your application. # Manual changes to this file will be overwritten if the code is regenerated. diff --git a/opencga-client/src/main/R/R/Panel-methods.R b/opencga-client/src/main/R/R/Panel-methods.R index 3d1c5bfb8d3..447c7f260e7 100644 --- a/opencga-client/src/main/R/R/Panel-methods.R +++ b/opencga-client/src/main/R/R/Panel-methods.R @@ -2,7 +2,7 @@ # WARNING: AUTOGENERATED CODE # # This code was generated by a tool. -# Autogenerated on: 2024-02-14 +# Autogenerated on: 2024-04-02 # # Manual changes to this file may cause unexpected behavior in your application. # Manual changes to this file will be overwritten if the code is regenerated. diff --git a/opencga-client/src/main/R/R/Project-methods.R b/opencga-client/src/main/R/R/Project-methods.R index ebbcb80dd92..2a990c23110 100644 --- a/opencga-client/src/main/R/R/Project-methods.R +++ b/opencga-client/src/main/R/R/Project-methods.R @@ -2,7 +2,7 @@ # WARNING: AUTOGENERATED CODE # # This code was generated by a tool. -# Autogenerated on: 2024-02-14 +# Autogenerated on: 2024-04-02 # # Manual changes to this file may cause unexpected behavior in your application. # Manual changes to this file will be overwritten if the code is regenerated. diff --git a/opencga-client/src/main/R/R/Sample-methods.R b/opencga-client/src/main/R/R/Sample-methods.R index c5f0bbd3357..d3236dcb5ff 100644 --- a/opencga-client/src/main/R/R/Sample-methods.R +++ b/opencga-client/src/main/R/R/Sample-methods.R @@ -2,7 +2,7 @@ # WARNING: AUTOGENERATED CODE # # This code was generated by a tool. -# Autogenerated on: 2024-02-14 +# Autogenerated on: 2024-04-02 # # Manual changes to this file may cause unexpected behavior in your application. # Manual changes to this file will be overwritten if the code is regenerated. @@ -39,7 +39,7 @@ #' [*]: Required parameter #' @export -setMethod("sampleClient", "OpencgaR", function(OpencgaR, samples, annotationSet, members, sample, endpointName, params=NULL, ...) { +setMethod("sampleClient", "OpencgaR", function(OpencgaR, annotationSet, members, sample, samples, endpointName, params=NULL, ...) { switch(endpointName, #' @section Endpoint /{apiVersion}/samples/acl/{members}/update: diff --git a/opencga-client/src/main/R/R/Study-methods.R b/opencga-client/src/main/R/R/Study-methods.R index c86c0da79b1..80dd512e819 100644 --- a/opencga-client/src/main/R/R/Study-methods.R +++ b/opencga-client/src/main/R/R/Study-methods.R @@ -2,7 +2,7 @@ # WARNING: AUTOGENERATED CODE # # This code was generated by a tool. -# Autogenerated on: 2024-02-14 +# Autogenerated on: 2024-04-02 # # Manual changes to this file may cause unexpected behavior in your application. # Manual changes to this file will be overwritten if the code is regenerated. @@ -46,7 +46,7 @@ #' [*]: Required parameter #' @export -setMethod("studyClient", "OpencgaR", function(OpencgaR, group, variableSet, studies, templateId, study, members, endpointName, params=NULL, ...) { +setMethod("studyClient", "OpencgaR", function(OpencgaR, study, group, studies, members, templateId, variableSet, endpointName, params=NULL, ...) { switch(endpointName, #' @section Endpoint /{apiVersion}/studies/acl/{members}/update: diff --git a/opencga-client/src/main/R/R/User-methods.R b/opencga-client/src/main/R/R/User-methods.R index fb403c674e6..6fa09e03fc5 100644 --- a/opencga-client/src/main/R/R/User-methods.R +++ b/opencga-client/src/main/R/R/User-methods.R @@ -2,7 +2,7 @@ # WARNING: AUTOGENERATED CODE # # This code was generated by a tool. -# Autogenerated on: 2024-02-14 +# Autogenerated on: 2024-04-02 # # Manual changes to this file may cause unexpected behavior in your application. # Manual changes to this file will be overwritten if the code is regenerated. @@ -38,7 +38,7 @@ #' [*]: Required parameter #' @export -setMethod("userClient", "OpencgaR", function(OpencgaR, user, users, filterId, endpointName, params=NULL, ...) { +setMethod("userClient", "OpencgaR", function(OpencgaR, filterId, users, user, endpointName, params=NULL, ...) { switch(endpointName, #' @section Endpoint /{apiVersion}/users/login: diff --git a/opencga-client/src/main/R/R/Variant-methods.R b/opencga-client/src/main/R/R/Variant-methods.R index d114e5d4882..2139d8a1a6d 100644 --- a/opencga-client/src/main/R/R/Variant-methods.R +++ b/opencga-client/src/main/R/R/Variant-methods.R @@ -2,7 +2,7 @@ # WARNING: AUTOGENERATED CODE # # This code was generated by a tool. -# Autogenerated on: 2024-02-14 +# Autogenerated on: 2024-04-02 # # Manual changes to this file may cause unexpected behavior in your application. # Manual changes to this file will be overwritten if the code is regenerated. diff --git a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/AdminClient.java b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/AdminClient.java index d4fcd4b1d60..ad1d3acb437 100644 --- a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/AdminClient.java +++ b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/AdminClient.java @@ -36,7 +36,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. -* Autogenerated on: 2024-02-14 +* Autogenerated on: 2024-04-02 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. @@ -45,7 +45,7 @@ /** * This class contains methods for the Admin webservices. - * Client version: 2.12.3-SNAPSHOT + * Client version: 2.12.4-SNAPSHOT * PATH: admin */ public class AdminClient extends AbstractParentClient { diff --git a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/AlignmentClient.java b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/AlignmentClient.java index c6c8c84fd8b..42c0aa02a6c 100644 --- a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/AlignmentClient.java +++ b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/AlignmentClient.java @@ -40,7 +40,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. -* Autogenerated on: 2024-02-14 +* Autogenerated on: 2024-04-02 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. @@ -49,7 +49,7 @@ /** * This class contains methods for the Alignment webservices. - * Client version: 2.12.3-SNAPSHOT + * Client version: 2.12.4-SNAPSHOT * PATH: analysis/alignment */ public class AlignmentClient extends AbstractParentClient { diff --git a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/ClinicalAnalysisClient.java b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/ClinicalAnalysisClient.java index e4858049e0b..0f1a735818d 100644 --- a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/ClinicalAnalysisClient.java +++ b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/ClinicalAnalysisClient.java @@ -54,7 +54,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. -* Autogenerated on: 2024-02-14 +* Autogenerated on: 2024-04-02 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. @@ -63,7 +63,7 @@ /** * This class contains methods for the ClinicalAnalysis webservices. - * Client version: 2.12.3-SNAPSHOT + * Client version: 2.12.4-SNAPSHOT * PATH: analysis/clinical */ public class ClinicalAnalysisClient extends AbstractParentClient { diff --git a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/CohortClient.java b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/CohortClient.java index f136be11310..edc593ea0df 100644 --- a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/CohortClient.java +++ b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/CohortClient.java @@ -37,7 +37,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. -* Autogenerated on: 2024-02-14 +* Autogenerated on: 2024-04-02 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. @@ -46,7 +46,7 @@ /** * This class contains methods for the Cohort webservices. - * Client version: 2.12.3-SNAPSHOT + * Client version: 2.12.4-SNAPSHOT * PATH: cohorts */ public class CohortClient extends AbstractParentClient { diff --git a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/DiseasePanelClient.java b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/DiseasePanelClient.java index 497e02f5445..42024d2cdb8 100644 --- a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/DiseasePanelClient.java +++ b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/DiseasePanelClient.java @@ -35,7 +35,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. -* Autogenerated on: 2024-02-14 +* Autogenerated on: 2024-04-02 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. @@ -44,7 +44,7 @@ /** * This class contains methods for the DiseasePanel webservices. - * Client version: 2.12.3-SNAPSHOT + * Client version: 2.12.4-SNAPSHOT * PATH: panels */ public class DiseasePanelClient extends AbstractParentClient { diff --git a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/FamilyClient.java b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/FamilyClient.java index 437d6e65255..cef93b298d4 100644 --- a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/FamilyClient.java +++ b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/FamilyClient.java @@ -36,7 +36,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. -* Autogenerated on: 2024-02-14 +* Autogenerated on: 2024-04-02 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. @@ -45,7 +45,7 @@ /** * This class contains methods for the Family webservices. - * Client version: 2.12.3-SNAPSHOT + * Client version: 2.12.4-SNAPSHOT * PATH: families */ public class FamilyClient extends AbstractParentClient { diff --git a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/FileClient.java b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/FileClient.java index 66ae008ab7c..727b4bdaa1b 100644 --- a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/FileClient.java +++ b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/FileClient.java @@ -43,7 +43,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. -* Autogenerated on: 2024-02-14 +* Autogenerated on: 2024-04-02 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. @@ -52,7 +52,7 @@ /** * This class contains methods for the File webservices. - * Client version: 2.12.3-SNAPSHOT + * Client version: 2.12.4-SNAPSHOT * PATH: files */ public class FileClient extends AbstractParentClient { diff --git a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/GA4GHClient.java b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/GA4GHClient.java index 5d007b409bd..29ba4b837db 100644 --- a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/GA4GHClient.java +++ b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/GA4GHClient.java @@ -27,7 +27,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. -* Autogenerated on: 2024-02-14 +* Autogenerated on: 2024-04-02 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. @@ -36,7 +36,7 @@ /** * This class contains methods for the GA4GH webservices. - * Client version: 2.12.3-SNAPSHOT + * Client version: 2.12.4-SNAPSHOT * PATH: ga4gh */ public class GA4GHClient extends AbstractParentClient { diff --git a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/IndividualClient.java b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/IndividualClient.java index 67bb7feb715..570b0c5e290 100644 --- a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/IndividualClient.java +++ b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/IndividualClient.java @@ -36,7 +36,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. -* Autogenerated on: 2024-02-14 +* Autogenerated on: 2024-04-02 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. @@ -45,7 +45,7 @@ /** * This class contains methods for the Individual webservices. - * Client version: 2.12.3-SNAPSHOT + * Client version: 2.12.4-SNAPSHOT * PATH: individuals */ public class IndividualClient extends AbstractParentClient { diff --git a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/JobClient.java b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/JobClient.java index c4fb407be93..dc70868534f 100644 --- a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/JobClient.java +++ b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/JobClient.java @@ -37,7 +37,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. -* Autogenerated on: 2024-02-14 +* Autogenerated on: 2024-04-02 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. @@ -46,7 +46,7 @@ /** * This class contains methods for the Job webservices. - * Client version: 2.12.3-SNAPSHOT + * Client version: 2.12.4-SNAPSHOT * PATH: jobs */ public class JobClient extends AbstractParentClient { diff --git a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/MetaClient.java b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/MetaClient.java index 4f1873c571c..c1038c2bcb1 100644 --- a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/MetaClient.java +++ b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/MetaClient.java @@ -28,7 +28,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. -* Autogenerated on: 2024-02-14 +* Autogenerated on: 2024-04-02 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. @@ -37,7 +37,7 @@ /** * This class contains methods for the Meta webservices. - * Client version: 2.12.3-SNAPSHOT + * Client version: 2.12.4-SNAPSHOT * PATH: meta */ public class MetaClient extends AbstractParentClient { diff --git a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/ProjectClient.java b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/ProjectClient.java index 19b3144a06d..46ff0306de0 100644 --- a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/ProjectClient.java +++ b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/ProjectClient.java @@ -32,7 +32,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. -* Autogenerated on: 2024-02-14 +* Autogenerated on: 2024-04-02 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. @@ -41,7 +41,7 @@ /** * This class contains methods for the Project webservices. - * Client version: 2.12.3-SNAPSHOT + * Client version: 2.12.4-SNAPSHOT * PATH: projects */ public class ProjectClient extends AbstractParentClient { diff --git a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/SampleClient.java b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/SampleClient.java index f1e5b7ac798..2e7dac9ea70 100644 --- a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/SampleClient.java +++ b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/SampleClient.java @@ -36,7 +36,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. -* Autogenerated on: 2024-02-14 +* Autogenerated on: 2024-04-02 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. @@ -45,7 +45,7 @@ /** * This class contains methods for the Sample webservices. - * Client version: 2.12.3-SNAPSHOT + * Client version: 2.12.4-SNAPSHOT * PATH: samples */ public class SampleClient extends AbstractParentClient { diff --git a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/StudyClient.java b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/StudyClient.java index 4a9b4550de8..9f304ec146b 100644 --- a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/StudyClient.java +++ b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/StudyClient.java @@ -45,7 +45,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. -* Autogenerated on: 2024-02-14 +* Autogenerated on: 2024-04-02 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. @@ -54,7 +54,7 @@ /** * This class contains methods for the Study webservices. - * Client version: 2.12.3-SNAPSHOT + * Client version: 2.12.4-SNAPSHOT * PATH: studies */ public class StudyClient extends AbstractParentClient { diff --git a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/UserClient.java b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/UserClient.java index bbf582a2cc6..a3258204820 100644 --- a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/UserClient.java +++ b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/UserClient.java @@ -36,7 +36,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. -* Autogenerated on: 2024-02-14 +* Autogenerated on: 2024-04-02 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. @@ -45,7 +45,7 @@ /** * This class contains methods for the User webservices. - * Client version: 2.12.3-SNAPSHOT + * Client version: 2.12.4-SNAPSHOT * PATH: users */ public class UserClient extends AbstractParentClient { diff --git a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/VariantClient.java b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/VariantClient.java index 1480df3ca9e..72a918c8f6a 100644 --- a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/VariantClient.java +++ b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/VariantClient.java @@ -32,6 +32,7 @@ import org.opencb.opencga.core.models.analysis.knockout.KnockoutByIndividual; import org.opencb.opencga.core.models.clinical.ExomiserWrapperParams; import org.opencb.opencga.core.models.job.Job; +import org.opencb.opencga.core.models.operations.variant.VariantIndexParams; import org.opencb.opencga.core.models.operations.variant.VariantStatsExportParams; import org.opencb.opencga.core.models.variant.CircosAnalysisParams; import org.opencb.opencga.core.models.variant.CohortVariantStatsAnalysisParams; @@ -53,7 +54,6 @@ import org.opencb.opencga.core.models.variant.SampleVariantFilterParams; import org.opencb.opencga.core.models.variant.SampleVariantStatsAnalysisParams; import org.opencb.opencga.core.models.variant.VariantExportParams; -import org.opencb.opencga.core.models.operations.variant.VariantIndexParams; import org.opencb.opencga.core.models.variant.VariantStatsAnalysisParams; import org.opencb.opencga.core.response.RestResponse; @@ -62,7 +62,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. -* Autogenerated on: 2024-02-14 +* Autogenerated on: 2024-04-02 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. @@ -71,7 +71,7 @@ /** * This class contains methods for the Variant webservices. - * Client version: 2.12.3-SNAPSHOT + * Client version: 2.12.4-SNAPSHOT * PATH: analysis/variant */ public class VariantClient extends AbstractParentClient { diff --git a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/VariantOperationClient.java b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/VariantOperationClient.java index 5351b58c869..e7e515c9357 100644 --- a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/VariantOperationClient.java +++ b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/VariantOperationClient.java @@ -28,19 +28,19 @@ import org.opencb.opencga.core.models.operations.variant.VariantAggregateParams; import org.opencb.opencga.core.models.operations.variant.VariantAnnotationIndexParams; import org.opencb.opencga.core.models.operations.variant.VariantAnnotationSaveParams; +import org.opencb.opencga.core.models.operations.variant.VariantConfigureParams; import org.opencb.opencga.core.models.operations.variant.VariantFamilyIndexParams; +import org.opencb.opencga.core.models.operations.variant.VariantFileDeleteParams; +import org.opencb.opencga.core.models.operations.variant.VariantFileIndexJobLauncherParams; +import org.opencb.opencga.core.models.operations.variant.VariantIndexParams; +import org.opencb.opencga.core.models.operations.variant.VariantPruneParams; +import org.opencb.opencga.core.models.operations.variant.VariantSampleDeleteParams; import org.opencb.opencga.core.models.operations.variant.VariantScoreIndexParams; import org.opencb.opencga.core.models.operations.variant.VariantSecondaryAnnotationIndexParams; import org.opencb.opencga.core.models.operations.variant.VariantSecondarySampleIndexParams; import org.opencb.opencga.core.models.operations.variant.VariantStatsDeleteParams; import org.opencb.opencga.core.models.operations.variant.VariantStatsIndexParams; import org.opencb.opencga.core.models.operations.variant.VariantStorageMetadataRepairToolParams; -import org.opencb.opencga.core.models.operations.variant.VariantConfigureParams; -import org.opencb.opencga.core.models.operations.variant.VariantFileDeleteParams; -import org.opencb.opencga.core.models.operations.variant.VariantFileIndexJobLauncherParams; -import org.opencb.opencga.core.models.operations.variant.VariantIndexParams; -import org.opencb.opencga.core.models.operations.variant.VariantPruneParams; -import org.opencb.opencga.core.models.operations.variant.VariantSampleDeleteParams; import org.opencb.opencga.core.models.operations.variant.VariantStorageMetadataSynchronizeParams; import org.opencb.opencga.core.models.operations.variant.VariantStudyDeleteParams; import org.opencb.opencga.core.response.RestResponse; @@ -50,7 +50,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. -* Autogenerated on: 2024-02-14 +* Autogenerated on: 2024-04-02 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. @@ -59,7 +59,7 @@ /** * This class contains methods for the VariantOperation webservices. - * Client version: 2.12.3-SNAPSHOT + * Client version: 2.12.4-SNAPSHOT * PATH: operation */ public class VariantOperationClient extends AbstractParentClient { diff --git a/opencga-client/src/main/javascript/Admin.js b/opencga-client/src/main/javascript/Admin.js index 30fe2d2b09b..2377deb6a5d 100644 --- a/opencga-client/src/main/javascript/Admin.js +++ b/opencga-client/src/main/javascript/Admin.js @@ -12,7 +12,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. - * Autogenerated on: 2024-02-14 + * Autogenerated on: 2024-04-02 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. diff --git a/opencga-client/src/main/javascript/Alignment.js b/opencga-client/src/main/javascript/Alignment.js index 764a51d164d..f19e3f9730a 100644 --- a/opencga-client/src/main/javascript/Alignment.js +++ b/opencga-client/src/main/javascript/Alignment.js @@ -12,7 +12,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. - * Autogenerated on: 2024-02-14 + * Autogenerated on: 2024-04-02 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. diff --git a/opencga-client/src/main/javascript/ClinicalAnalysis.js b/opencga-client/src/main/javascript/ClinicalAnalysis.js index 1556652d3d3..43355233c98 100644 --- a/opencga-client/src/main/javascript/ClinicalAnalysis.js +++ b/opencga-client/src/main/javascript/ClinicalAnalysis.js @@ -12,7 +12,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. - * Autogenerated on: 2024-02-14 + * Autogenerated on: 2024-04-02 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. diff --git a/opencga-client/src/main/javascript/Cohort.js b/opencga-client/src/main/javascript/Cohort.js index 97ef19dcbdf..eed9d670e97 100644 --- a/opencga-client/src/main/javascript/Cohort.js +++ b/opencga-client/src/main/javascript/Cohort.js @@ -12,7 +12,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. - * Autogenerated on: 2024-02-14 + * Autogenerated on: 2024-04-02 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. diff --git a/opencga-client/src/main/javascript/DiseasePanel.js b/opencga-client/src/main/javascript/DiseasePanel.js index 52601203a30..ad3750dddd8 100644 --- a/opencga-client/src/main/javascript/DiseasePanel.js +++ b/opencga-client/src/main/javascript/DiseasePanel.js @@ -12,7 +12,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. - * Autogenerated on: 2024-02-14 + * Autogenerated on: 2024-04-02 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. diff --git a/opencga-client/src/main/javascript/Family.js b/opencga-client/src/main/javascript/Family.js index 608c23c087d..cc2a5e7fd84 100644 --- a/opencga-client/src/main/javascript/Family.js +++ b/opencga-client/src/main/javascript/Family.js @@ -12,7 +12,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. - * Autogenerated on: 2024-02-14 + * Autogenerated on: 2024-04-02 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. diff --git a/opencga-client/src/main/javascript/File.js b/opencga-client/src/main/javascript/File.js index f09d5c4562f..a512552f575 100644 --- a/opencga-client/src/main/javascript/File.js +++ b/opencga-client/src/main/javascript/File.js @@ -12,7 +12,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. - * Autogenerated on: 2024-02-14 + * Autogenerated on: 2024-04-02 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. diff --git a/opencga-client/src/main/javascript/GA4GH.js b/opencga-client/src/main/javascript/GA4GH.js index b656c0bd696..ad65f679658 100644 --- a/opencga-client/src/main/javascript/GA4GH.js +++ b/opencga-client/src/main/javascript/GA4GH.js @@ -12,7 +12,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. - * Autogenerated on: 2024-02-14 + * Autogenerated on: 2024-04-02 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. diff --git a/opencga-client/src/main/javascript/Individual.js b/opencga-client/src/main/javascript/Individual.js index d8bd896ae88..3446e95a702 100644 --- a/opencga-client/src/main/javascript/Individual.js +++ b/opencga-client/src/main/javascript/Individual.js @@ -12,7 +12,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. - * Autogenerated on: 2024-02-14 + * Autogenerated on: 2024-04-02 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. diff --git a/opencga-client/src/main/javascript/Job.js b/opencga-client/src/main/javascript/Job.js index 9489c82bc7a..2ed4db0e9b4 100644 --- a/opencga-client/src/main/javascript/Job.js +++ b/opencga-client/src/main/javascript/Job.js @@ -12,7 +12,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. - * Autogenerated on: 2024-02-14 + * Autogenerated on: 2024-04-02 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. diff --git a/opencga-client/src/main/javascript/Meta.js b/opencga-client/src/main/javascript/Meta.js index b5636ff6a5e..8a452420625 100644 --- a/opencga-client/src/main/javascript/Meta.js +++ b/opencga-client/src/main/javascript/Meta.js @@ -12,7 +12,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. - * Autogenerated on: 2024-02-14 + * Autogenerated on: 2024-04-02 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. diff --git a/opencga-client/src/main/javascript/Project.js b/opencga-client/src/main/javascript/Project.js index bde7382c84d..6c5dc015c14 100644 --- a/opencga-client/src/main/javascript/Project.js +++ b/opencga-client/src/main/javascript/Project.js @@ -12,7 +12,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. - * Autogenerated on: 2024-02-14 + * Autogenerated on: 2024-04-02 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. diff --git a/opencga-client/src/main/javascript/Sample.js b/opencga-client/src/main/javascript/Sample.js index 990f3b3b04e..6a10489e885 100644 --- a/opencga-client/src/main/javascript/Sample.js +++ b/opencga-client/src/main/javascript/Sample.js @@ -12,7 +12,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. - * Autogenerated on: 2024-02-14 + * Autogenerated on: 2024-04-02 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. diff --git a/opencga-client/src/main/javascript/Study.js b/opencga-client/src/main/javascript/Study.js index 7d443653ad9..9d68b8ecb87 100644 --- a/opencga-client/src/main/javascript/Study.js +++ b/opencga-client/src/main/javascript/Study.js @@ -12,7 +12,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. - * Autogenerated on: 2024-02-14 + * Autogenerated on: 2024-04-02 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. diff --git a/opencga-client/src/main/javascript/User.js b/opencga-client/src/main/javascript/User.js index 2093a3aadb4..b008e70997a 100644 --- a/opencga-client/src/main/javascript/User.js +++ b/opencga-client/src/main/javascript/User.js @@ -12,7 +12,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. - * Autogenerated on: 2024-02-14 + * Autogenerated on: 2024-04-02 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. diff --git a/opencga-client/src/main/javascript/Variant.js b/opencga-client/src/main/javascript/Variant.js index c98bccd6bf5..1874e9b146d 100644 --- a/opencga-client/src/main/javascript/Variant.js +++ b/opencga-client/src/main/javascript/Variant.js @@ -12,7 +12,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. - * Autogenerated on: 2024-02-14 + * Autogenerated on: 2024-04-02 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. diff --git a/opencga-client/src/main/javascript/VariantOperation.js b/opencga-client/src/main/javascript/VariantOperation.js index ad54d4104cf..65132601a6d 100644 --- a/opencga-client/src/main/javascript/VariantOperation.js +++ b/opencga-client/src/main/javascript/VariantOperation.js @@ -12,7 +12,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. - * Autogenerated on: 2024-02-14 + * Autogenerated on: 2024-04-02 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. diff --git a/opencga-client/src/main/python/pyopencga/rest_clients/admin_client.py b/opencga-client/src/main/python/pyopencga/rest_clients/admin_client.py index 4a60e9c7e2f..3cc57636937 100644 --- a/opencga-client/src/main/python/pyopencga/rest_clients/admin_client.py +++ b/opencga-client/src/main/python/pyopencga/rest_clients/admin_client.py @@ -2,7 +2,7 @@ WARNING: AUTOGENERATED CODE This code was generated by a tool. - Autogenerated on: 2024-02-14 + Autogenerated on: 2024-04-02 Manual changes to this file may cause unexpected behavior in your application. Manual changes to this file will be overwritten if the code is regenerated. @@ -14,7 +14,7 @@ class Admin(_ParentRestClient): """ This class contains methods for the 'Admin' webservices - Client version: 2.12.3-SNAPSHOT + Client version: 2.12.4-SNAPSHOT PATH: /{apiVersion}/admin """ diff --git a/opencga-client/src/main/python/pyopencga/rest_clients/alignment_client.py b/opencga-client/src/main/python/pyopencga/rest_clients/alignment_client.py index 98b40a3f711..54e58d84df2 100644 --- a/opencga-client/src/main/python/pyopencga/rest_clients/alignment_client.py +++ b/opencga-client/src/main/python/pyopencga/rest_clients/alignment_client.py @@ -2,7 +2,7 @@ WARNING: AUTOGENERATED CODE This code was generated by a tool. - Autogenerated on: 2024-02-14 + Autogenerated on: 2024-04-02 Manual changes to this file may cause unexpected behavior in your application. Manual changes to this file will be overwritten if the code is regenerated. @@ -14,7 +14,7 @@ class Alignment(_ParentRestClient): """ This class contains methods for the 'Analysis - Alignment' webservices - Client version: 2.12.3-SNAPSHOT + Client version: 2.12.4-SNAPSHOT PATH: /{apiVersion}/analysis/alignment """ diff --git a/opencga-client/src/main/python/pyopencga/rest_clients/clinical_analysis_client.py b/opencga-client/src/main/python/pyopencga/rest_clients/clinical_analysis_client.py index 1e4a73902cc..9b385f43826 100644 --- a/opencga-client/src/main/python/pyopencga/rest_clients/clinical_analysis_client.py +++ b/opencga-client/src/main/python/pyopencga/rest_clients/clinical_analysis_client.py @@ -2,7 +2,7 @@ WARNING: AUTOGENERATED CODE This code was generated by a tool. - Autogenerated on: 2024-02-14 + Autogenerated on: 2024-04-02 Manual changes to this file may cause unexpected behavior in your application. Manual changes to this file will be overwritten if the code is regenerated. @@ -14,7 +14,7 @@ class ClinicalAnalysis(_ParentRestClient): """ This class contains methods for the 'Analysis - Clinical' webservices - Client version: 2.12.3-SNAPSHOT + Client version: 2.12.4-SNAPSHOT PATH: /{apiVersion}/analysis/clinical """ diff --git a/opencga-client/src/main/python/pyopencga/rest_clients/cohort_client.py b/opencga-client/src/main/python/pyopencga/rest_clients/cohort_client.py index 50af2a865a2..eebf5207dd3 100644 --- a/opencga-client/src/main/python/pyopencga/rest_clients/cohort_client.py +++ b/opencga-client/src/main/python/pyopencga/rest_clients/cohort_client.py @@ -2,7 +2,7 @@ WARNING: AUTOGENERATED CODE This code was generated by a tool. - Autogenerated on: 2024-02-14 + Autogenerated on: 2024-04-02 Manual changes to this file may cause unexpected behavior in your application. Manual changes to this file will be overwritten if the code is regenerated. @@ -14,7 +14,7 @@ class Cohort(_ParentRestClient): """ This class contains methods for the 'Cohorts' webservices - Client version: 2.12.3-SNAPSHOT + Client version: 2.12.4-SNAPSHOT PATH: /{apiVersion}/cohorts """ diff --git a/opencga-client/src/main/python/pyopencga/rest_clients/disease_panel_client.py b/opencga-client/src/main/python/pyopencga/rest_clients/disease_panel_client.py index e234b2ff148..cad832f07e3 100644 --- a/opencga-client/src/main/python/pyopencga/rest_clients/disease_panel_client.py +++ b/opencga-client/src/main/python/pyopencga/rest_clients/disease_panel_client.py @@ -2,7 +2,7 @@ WARNING: AUTOGENERATED CODE This code was generated by a tool. - Autogenerated on: 2024-02-14 + Autogenerated on: 2024-04-02 Manual changes to this file may cause unexpected behavior in your application. Manual changes to this file will be overwritten if the code is regenerated. @@ -14,7 +14,7 @@ class DiseasePanel(_ParentRestClient): """ This class contains methods for the 'Disease Panels' webservices - Client version: 2.12.3-SNAPSHOT + Client version: 2.12.4-SNAPSHOT PATH: /{apiVersion}/panels """ diff --git a/opencga-client/src/main/python/pyopencga/rest_clients/family_client.py b/opencga-client/src/main/python/pyopencga/rest_clients/family_client.py index 4fd32087258..3401712dbf8 100644 --- a/opencga-client/src/main/python/pyopencga/rest_clients/family_client.py +++ b/opencga-client/src/main/python/pyopencga/rest_clients/family_client.py @@ -2,7 +2,7 @@ WARNING: AUTOGENERATED CODE This code was generated by a tool. - Autogenerated on: 2024-02-14 + Autogenerated on: 2024-04-02 Manual changes to this file may cause unexpected behavior in your application. Manual changes to this file will be overwritten if the code is regenerated. @@ -14,7 +14,7 @@ class Family(_ParentRestClient): """ This class contains methods for the 'Families' webservices - Client version: 2.12.3-SNAPSHOT + Client version: 2.12.4-SNAPSHOT PATH: /{apiVersion}/families """ diff --git a/opencga-client/src/main/python/pyopencga/rest_clients/file_client.py b/opencga-client/src/main/python/pyopencga/rest_clients/file_client.py index 22e58ba63be..ef79d272d7b 100644 --- a/opencga-client/src/main/python/pyopencga/rest_clients/file_client.py +++ b/opencga-client/src/main/python/pyopencga/rest_clients/file_client.py @@ -2,7 +2,7 @@ WARNING: AUTOGENERATED CODE This code was generated by a tool. - Autogenerated on: 2024-02-14 + Autogenerated on: 2024-04-02 Manual changes to this file may cause unexpected behavior in your application. Manual changes to this file will be overwritten if the code is regenerated. @@ -14,7 +14,7 @@ class File(_ParentRestClient): """ This class contains methods for the 'Files' webservices - Client version: 2.12.3-SNAPSHOT + Client version: 2.12.4-SNAPSHOT PATH: /{apiVersion}/files """ diff --git a/opencga-client/src/main/python/pyopencga/rest_clients/ga4gh_client.py b/opencga-client/src/main/python/pyopencga/rest_clients/ga4gh_client.py index b15c6e8bd76..55b32f7a9a3 100644 --- a/opencga-client/src/main/python/pyopencga/rest_clients/ga4gh_client.py +++ b/opencga-client/src/main/python/pyopencga/rest_clients/ga4gh_client.py @@ -2,7 +2,7 @@ WARNING: AUTOGENERATED CODE This code was generated by a tool. - Autogenerated on: 2024-02-14 + Autogenerated on: 2024-04-02 Manual changes to this file may cause unexpected behavior in your application. Manual changes to this file will be overwritten if the code is regenerated. @@ -14,7 +14,7 @@ class GA4GH(_ParentRestClient): """ This class contains methods for the 'GA4GH' webservices - Client version: 2.12.3-SNAPSHOT + Client version: 2.12.4-SNAPSHOT PATH: /{apiVersion}/ga4gh """ diff --git a/opencga-client/src/main/python/pyopencga/rest_clients/individual_client.py b/opencga-client/src/main/python/pyopencga/rest_clients/individual_client.py index 3b393328993..65ab19393dd 100644 --- a/opencga-client/src/main/python/pyopencga/rest_clients/individual_client.py +++ b/opencga-client/src/main/python/pyopencga/rest_clients/individual_client.py @@ -2,7 +2,7 @@ WARNING: AUTOGENERATED CODE This code was generated by a tool. - Autogenerated on: 2024-02-14 + Autogenerated on: 2024-04-02 Manual changes to this file may cause unexpected behavior in your application. Manual changes to this file will be overwritten if the code is regenerated. @@ -14,7 +14,7 @@ class Individual(_ParentRestClient): """ This class contains methods for the 'Individuals' webservices - Client version: 2.12.3-SNAPSHOT + Client version: 2.12.4-SNAPSHOT PATH: /{apiVersion}/individuals """ diff --git a/opencga-client/src/main/python/pyopencga/rest_clients/job_client.py b/opencga-client/src/main/python/pyopencga/rest_clients/job_client.py index 1d5369c4639..1a9e30fa472 100644 --- a/opencga-client/src/main/python/pyopencga/rest_clients/job_client.py +++ b/opencga-client/src/main/python/pyopencga/rest_clients/job_client.py @@ -2,7 +2,7 @@ WARNING: AUTOGENERATED CODE This code was generated by a tool. - Autogenerated on: 2024-02-14 + Autogenerated on: 2024-04-02 Manual changes to this file may cause unexpected behavior in your application. Manual changes to this file will be overwritten if the code is regenerated. @@ -14,7 +14,7 @@ class Job(_ParentRestClient): """ This class contains methods for the 'Jobs' webservices - Client version: 2.12.3-SNAPSHOT + Client version: 2.12.4-SNAPSHOT PATH: /{apiVersion}/jobs """ diff --git a/opencga-client/src/main/python/pyopencga/rest_clients/meta_client.py b/opencga-client/src/main/python/pyopencga/rest_clients/meta_client.py index 1506926345b..91f1a0148c4 100644 --- a/opencga-client/src/main/python/pyopencga/rest_clients/meta_client.py +++ b/opencga-client/src/main/python/pyopencga/rest_clients/meta_client.py @@ -2,7 +2,7 @@ WARNING: AUTOGENERATED CODE This code was generated by a tool. - Autogenerated on: 2024-02-14 + Autogenerated on: 2024-04-02 Manual changes to this file may cause unexpected behavior in your application. Manual changes to this file will be overwritten if the code is regenerated. @@ -14,7 +14,7 @@ class Meta(_ParentRestClient): """ This class contains methods for the 'Meta' webservices - Client version: 2.12.3-SNAPSHOT + Client version: 2.12.4-SNAPSHOT PATH: /{apiVersion}/meta """ diff --git a/opencga-client/src/main/python/pyopencga/rest_clients/project_client.py b/opencga-client/src/main/python/pyopencga/rest_clients/project_client.py index 338e65d466c..9265e6cb11c 100644 --- a/opencga-client/src/main/python/pyopencga/rest_clients/project_client.py +++ b/opencga-client/src/main/python/pyopencga/rest_clients/project_client.py @@ -2,7 +2,7 @@ WARNING: AUTOGENERATED CODE This code was generated by a tool. - Autogenerated on: 2024-02-14 + Autogenerated on: 2024-04-02 Manual changes to this file may cause unexpected behavior in your application. Manual changes to this file will be overwritten if the code is regenerated. @@ -14,7 +14,7 @@ class Project(_ParentRestClient): """ This class contains methods for the 'Projects' webservices - Client version: 2.12.3-SNAPSHOT + Client version: 2.12.4-SNAPSHOT PATH: /{apiVersion}/projects """ diff --git a/opencga-client/src/main/python/pyopencga/rest_clients/sample_client.py b/opencga-client/src/main/python/pyopencga/rest_clients/sample_client.py index e83e98d3be2..01affe601e3 100644 --- a/opencga-client/src/main/python/pyopencga/rest_clients/sample_client.py +++ b/opencga-client/src/main/python/pyopencga/rest_clients/sample_client.py @@ -2,7 +2,7 @@ WARNING: AUTOGENERATED CODE This code was generated by a tool. - Autogenerated on: 2024-02-14 + Autogenerated on: 2024-04-02 Manual changes to this file may cause unexpected behavior in your application. Manual changes to this file will be overwritten if the code is regenerated. @@ -14,7 +14,7 @@ class Sample(_ParentRestClient): """ This class contains methods for the 'Samples' webservices - Client version: 2.12.3-SNAPSHOT + Client version: 2.12.4-SNAPSHOT PATH: /{apiVersion}/samples """ diff --git a/opencga-client/src/main/python/pyopencga/rest_clients/study_client.py b/opencga-client/src/main/python/pyopencga/rest_clients/study_client.py index 17fda942ec7..620c5e3fdc6 100644 --- a/opencga-client/src/main/python/pyopencga/rest_clients/study_client.py +++ b/opencga-client/src/main/python/pyopencga/rest_clients/study_client.py @@ -2,7 +2,7 @@ WARNING: AUTOGENERATED CODE This code was generated by a tool. - Autogenerated on: 2024-02-14 + Autogenerated on: 2024-04-02 Manual changes to this file may cause unexpected behavior in your application. Manual changes to this file will be overwritten if the code is regenerated. @@ -14,7 +14,7 @@ class Study(_ParentRestClient): """ This class contains methods for the 'Studies' webservices - Client version: 2.12.3-SNAPSHOT + Client version: 2.12.4-SNAPSHOT PATH: /{apiVersion}/studies """ diff --git a/opencga-client/src/main/python/pyopencga/rest_clients/user_client.py b/opencga-client/src/main/python/pyopencga/rest_clients/user_client.py index f991cf25dae..b684890bcab 100644 --- a/opencga-client/src/main/python/pyopencga/rest_clients/user_client.py +++ b/opencga-client/src/main/python/pyopencga/rest_clients/user_client.py @@ -2,7 +2,7 @@ WARNING: AUTOGENERATED CODE This code was generated by a tool. - Autogenerated on: 2024-02-14 + Autogenerated on: 2024-04-02 Manual changes to this file may cause unexpected behavior in your application. Manual changes to this file will be overwritten if the code is regenerated. @@ -14,7 +14,7 @@ class User(_ParentRestClient): """ This class contains methods for the 'Users' webservices - Client version: 2.12.3-SNAPSHOT + Client version: 2.12.4-SNAPSHOT PATH: /{apiVersion}/users """ diff --git a/opencga-client/src/main/python/pyopencga/rest_clients/variant_client.py b/opencga-client/src/main/python/pyopencga/rest_clients/variant_client.py index 57cd7a1a9cf..cf74d9e49c8 100644 --- a/opencga-client/src/main/python/pyopencga/rest_clients/variant_client.py +++ b/opencga-client/src/main/python/pyopencga/rest_clients/variant_client.py @@ -2,7 +2,7 @@ WARNING: AUTOGENERATED CODE This code was generated by a tool. - Autogenerated on: 2024-02-14 + Autogenerated on: 2024-04-02 Manual changes to this file may cause unexpected behavior in your application. Manual changes to this file will be overwritten if the code is regenerated. @@ -14,7 +14,7 @@ class Variant(_ParentRestClient): """ This class contains methods for the 'Analysis - Variant' webservices - Client version: 2.12.3-SNAPSHOT + Client version: 2.12.4-SNAPSHOT PATH: /{apiVersion}/analysis/variant """ diff --git a/opencga-client/src/main/python/pyopencga/rest_clients/variant_operation_client.py b/opencga-client/src/main/python/pyopencga/rest_clients/variant_operation_client.py index b48bb9d8ad4..315ddf4e234 100644 --- a/opencga-client/src/main/python/pyopencga/rest_clients/variant_operation_client.py +++ b/opencga-client/src/main/python/pyopencga/rest_clients/variant_operation_client.py @@ -2,7 +2,7 @@ WARNING: AUTOGENERATED CODE This code was generated by a tool. - Autogenerated on: 2024-02-14 + Autogenerated on: 2024-04-02 Manual changes to this file may cause unexpected behavior in your application. Manual changes to this file will be overwritten if the code is regenerated. @@ -14,7 +14,7 @@ class VariantOperation(_ParentRestClient): """ This class contains methods for the 'Operations - Variant Storage' webservices - Client version: 2.12.3-SNAPSHOT + Client version: 2.12.4-SNAPSHOT PATH: /{apiVersion}/operation """ From f9f40511b9afc65120dde7583dfff03e1d8040e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacobo=20Coll=20Morag=C3=B3n?= Date: Wed, 3 Apr 2024 16:38:54 +0100 Subject: [PATCH 19/85] pom: Add log4j2-test.xml #TASK-5603 --- opencga-analysis/pom.xml | 8 ++++++++ opencga-catalog/pom.xml | 6 ++++++ .../src/test/resources/log4j2-test.xml | 20 +++++++++++++++++++ 3 files changed, 34 insertions(+) create mode 100644 opencga-core/src/test/resources/log4j2-test.xml diff --git a/opencga-analysis/pom.xml b/opencga-analysis/pom.xml index 8f1dbb61469..abd6d563378 100644 --- a/opencga-analysis/pom.xml +++ b/opencga-analysis/pom.xml @@ -243,6 +243,14 @@ + + + ../opencga-core/src/test/resources + + log4j2-test.xml + + + org.apache.maven.plugins diff --git a/opencga-catalog/pom.xml b/opencga-catalog/pom.xml index 7a4dd21139b..e20025edd44 100644 --- a/opencga-catalog/pom.xml +++ b/opencga-catalog/pom.xml @@ -265,6 +265,12 @@ template.zip + + ../opencga-core/src/test/resources + + log4j2-test.xml + + diff --git a/opencga-core/src/test/resources/log4j2-test.xml b/opencga-core/src/test/resources/log4j2-test.xml new file mode 100644 index 00000000000..dce741b72cb --- /dev/null +++ b/opencga-core/src/test/resources/log4j2-test.xml @@ -0,0 +1,20 @@ + + + + ${sys:opencga.log.level:-info} + + + + + + + + + + + + + + + + \ No newline at end of file From 8b9b5a3d098e9faf71585baab9a263861e750450 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacobo=20Coll=20Morag=C3=B3n?= Date: Tue, 9 Apr 2024 00:30:38 +0100 Subject: [PATCH 20/85] analysis: Fix PlatinumFileIndexerTest #TASK-6007 --- .../variant/manager/operations/PlatinumFileIndexerTest.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/opencga-analysis/src/test/java/org/opencb/opencga/analysis/variant/manager/operations/PlatinumFileIndexerTest.java b/opencga-analysis/src/test/java/org/opencb/opencga/analysis/variant/manager/operations/PlatinumFileIndexerTest.java index c109362961a..f62d332470b 100644 --- a/opencga-analysis/src/test/java/org/opencb/opencga/analysis/variant/manager/operations/PlatinumFileIndexerTest.java +++ b/opencga-analysis/src/test/java/org/opencb/opencga/analysis/variant/manager/operations/PlatinumFileIndexerTest.java @@ -107,9 +107,8 @@ public void testIndexFamily() throws Exception { ExecutionResult er = toolRunner.execute(VariantIndexOperationTool.class, params.toObjectMap() .append(ParamConstants.STUDY_PARAM, studyId), outDir, null, sessionId); - assertEquals(2, er.getSteps().size()); + assertEquals(1, er.getSteps().size()); assertEquals("variant-index", er.getSteps().get(0).getId()); - assertEquals("family-index", er.getSteps().get(1).getId()); variantManager.iterator(new Query(VariantQueryParam.STUDY.key(), studyId), new QueryOptions(), sessionId).forEachRemaining(variant -> { System.out.println("variant = " + variant); From 8875ff0e4944c349f8aba13895de695c3de862c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacobo=20Coll=20Morag=C3=B3n?= Date: Tue, 9 Apr 2024 00:55:40 +0100 Subject: [PATCH 21/85] storage: Allow hgvs filtering via xrefs. #TASK-5878 --- .../core/variant/adaptors/VariantQuery.java | 14 +- .../variant/adaptors/VariantQueryParam.java | 2 +- .../VariantAnnotationModelUtils.java | 114 ++++++++ .../variant/query/ParsedVariantQuery.java | 11 + .../variant/query/VariantQueryParser.java | 2 +- .../core/variant/query/VariantQueryUtils.java | 11 + ...AbstractTwoPhasedVariantQueryExecutor.java | 2 +- .../VariantSearchToVariantConverter.java | 66 ++--- .../adaptors/VariantDBAdaptorTest.java | 61 +++-- .../executors/VariantQueryExecutorTest.java | 246 ++++++++++++++++++ .../VariantAnnotationToPhoenixConverter.java | 29 +-- .../SampleIndexVariantQueryExecutor.java | 6 +- .../HadoopVariantQueryExecutorTest.java | 30 +++ 13 files changed, 490 insertions(+), 104 deletions(-) create mode 100644 opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/annotation/converters/VariantAnnotationModelUtils.java create mode 100644 opencga-storage/opencga-storage-core/src/test/java/org/opencb/opencga/storage/core/variant/query/executors/VariantQueryExecutorTest.java create mode 100644 opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/test/java/org/opencb/opencga/storage/hadoop/variant/query/executors/HadoopVariantQueryExecutorTest.java diff --git a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/adaptors/VariantQuery.java b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/adaptors/VariantQuery.java index 65c2bda05e6..9c04ad9c9bf 100644 --- a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/adaptors/VariantQuery.java +++ b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/adaptors/VariantQuery.java @@ -105,6 +105,15 @@ public VariantQuery sample(String value) { return sample(VariantQueryUtils.QueryOperation.OR, value); } + public VariantQuery sample(List value) { + return sample(VariantQueryUtils.QueryOperation.OR, value); + } + + public VariantQuery sample(VariantQueryUtils.QueryOperation operation, List value) { + put(VariantQueryParam.SAMPLE.key(), value.stream().collect(Collectors.joining(operation.separator()))); + return this; + } + public VariantQuery sample(String... value) { return sample(VariantQueryUtils.QueryOperation.OR, value); } @@ -178,8 +187,9 @@ public VariantQuery includeSampleId(boolean value) { put(VariantQueryParam.INCLUDE_SAMPLE_ID.key(), value); return this; } - public String includeSampleId() { - return getString(VariantQueryParam.INCLUDE_SAMPLE_ID.key()); + + public boolean includeSampleId() { + return getBoolean(VariantQueryParam.INCLUDE_SAMPLE_ID.key()); } public VariantQuery sampleMetadata(boolean value) { diff --git a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/adaptors/VariantQueryParam.java b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/adaptors/VariantQueryParam.java index b021b0e1382..f2d03ba6ddb 100644 --- a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/adaptors/VariantQueryParam.java +++ b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/adaptors/VariantQueryParam.java @@ -215,7 +215,7 @@ public final class VariantQueryParam implements QueryParam { public static final String ANNOT_XREF_DESCR = "List of any external reference, these can be genes, proteins or variants. " - + "Accepted IDs include HGNC, Ensembl genes, dbSNP, ClinVar, HPO, Cosmic, ..."; + + "Accepted IDs include HGNC, Ensembl genes, dbSNP, ClinVar, HPO, Cosmic, HGVS ..."; public static final VariantQueryParam ANNOT_XREF = new VariantQueryParam("xref", TEXT_ARRAY, ANNOT_XREF_DESCR); public static final String GENE_DESCR diff --git a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/annotation/converters/VariantAnnotationModelUtils.java b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/annotation/converters/VariantAnnotationModelUtils.java new file mode 100644 index 00000000000..cb317120362 --- /dev/null +++ b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/annotation/converters/VariantAnnotationModelUtils.java @@ -0,0 +1,114 @@ +package org.opencb.opencga.storage.core.variant.annotation.converters; + +import org.apache.commons.collections4.CollectionUtils; +import org.opencb.biodata.models.variant.avro.*; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +public class VariantAnnotationModelUtils { + + /** + * Extracts all the XRefs from a VariantAnnotation object. + * Includes: + * - annotation.id + * - annotation.xrefs.id + * - annotation.cytoband.chromosome + cytoband.name + * - annotation.hgvs + * - annotation.consequenceTypes.geneName + * - annotation.consequenceTypes.geneId + * - annotation.consequenceTypes.ensemblGeneId + * - annotation.consequenceTypes.transcriptId + * - annotation.consequenceTypes.ensemblTranscriptId + * - annotation.consequenceTypes.hgvs + * - annotation.consequenceTypes.proteinVariantAnnotation.uniprotAccession + * - annotation.consequenceTypes.proteinVariantAnnotation.uniprotName + * - annotation.consequenceTypes.proteinVariantAnnotation.uniprotVariantId + * - annotation.consequenceTypes.proteinVariantAnnotation.features.id + * - annotation.traitAssociation.id + * - annotation.geneTraitAssociation.hpo + * - annotation.geneTraitAssociation.id + * + * @param variantAnnotation VariantAnnotation object + * @return Set of XRefs + */ + public Set extractXRefs(VariantAnnotation variantAnnotation) { + Set xrefs = new HashSet<>(); + + if (variantAnnotation == null) { + return xrefs; + } + + xrefs.add(variantAnnotation.getId()); + + if (variantAnnotation.getXrefs() != null) { + for (Xref xref : variantAnnotation.getXrefs()) { + if (xref != null) { + xrefs.add(xref.getId()); + } + } + } + + if (variantAnnotation.getCytoband() != null) { + for (Cytoband cytoband : variantAnnotation.getCytoband()) { + // TODO: Why do we need to add the chromosome name? + xrefs.add(cytoband.getChromosome() + cytoband.getName()); + } + } + + if (variantAnnotation.getHgvs() != null) { + xrefs.addAll(variantAnnotation.getHgvs()); + } + + List consequenceTypes = variantAnnotation.getConsequenceTypes(); + if (consequenceTypes != null) { + for (ConsequenceType conseqType : consequenceTypes) { + xrefs.add(conseqType.getGeneName()); + xrefs.add(conseqType.getGeneId()); + xrefs.add(conseqType.getEnsemblGeneId()); + xrefs.add(conseqType.getTranscriptId()); + xrefs.add(conseqType.getEnsemblTranscriptId()); + + if (conseqType.getHgvs() != null) { + xrefs.addAll(conseqType.getHgvs()); + } + + ProteinVariantAnnotation protVarAnnotation = conseqType.getProteinVariantAnnotation(); + if (protVarAnnotation != null) { + + xrefs.add(protVarAnnotation.getUniprotAccession()); + xrefs.add(protVarAnnotation.getUniprotName()); + xrefs.add(protVarAnnotation.getUniprotVariantId()); + + if (protVarAnnotation.getFeatures() != null) { + for (ProteinFeature proteinFeature : protVarAnnotation.getFeatures()) { + xrefs.add(proteinFeature.getId()); + } + } + } + } + + } + + if (CollectionUtils.isNotEmpty(variantAnnotation.getTraitAssociation())) { + for (EvidenceEntry evidenceEntry : variantAnnotation.getTraitAssociation()) { + xrefs.add(evidenceEntry.getId()); + } + } + + if (variantAnnotation.getGeneTraitAssociation() != null) { + for (GeneTraitAssociation geneTrait : variantAnnotation.getGeneTraitAssociation()) { + xrefs.add(geneTrait.getHpo()); + xrefs.add(geneTrait.getId()); + } + } + + // Remove empty strings and nulls + xrefs.remove(""); + xrefs.remove(null); + + return xrefs; + } + +} diff --git a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/ParsedVariantQuery.java b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/ParsedVariantQuery.java index 9c89ffb5b61..5c90df943fc 100644 --- a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/ParsedVariantQuery.java +++ b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/ParsedVariantQuery.java @@ -226,5 +226,16 @@ public List getIDsAndXrefs() { public boolean isEmpty() { return genes.isEmpty() && variants.isEmpty() && ids.isEmpty() && otherXrefs.isEmpty(); } + + @Override + public String toString() { + final StringBuilder sb = new StringBuilder("VariantQueryXref{"); + sb.append("genes=").append(genes); + sb.append(", variants=").append(variants); + sb.append(", ids=").append(ids); + sb.append(", otherXrefs=").append(otherXrefs); + sb.append('}'); + return sb.toString(); + } } } diff --git a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/VariantQueryParser.java b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/VariantQueryParser.java index 1564ad0fabf..21c1124c88e 100644 --- a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/VariantQueryParser.java +++ b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/VariantQueryParser.java @@ -851,7 +851,7 @@ public static ParsedVariantQuery.VariantQueryXref parseXrefs(Query query) { if (variant != null) { xrefs.getVariants().add(variant); } else { - if (isVariantAccession(value) || isClinicalAccession(value) || isGeneAccession(value)) { + if (isVariantAccession(value) || isClinicalAccession(value) || isGeneAccession(value) || isHGVS(value)) { xrefs.getOtherXrefs().add(value); } else { genes.add(value); diff --git a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/VariantQueryUtils.java b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/VariantQueryUtils.java index 114379c77a9..c11c3f64634 100644 --- a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/VariantQueryUtils.java +++ b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/VariantQueryUtils.java @@ -466,6 +466,17 @@ public static boolean isVariantAccession(String value) { return value.startsWith("rs") || value.startsWith("VAR_"); } + /** + * Determines if the given value is a HGVS. + * + * @param value Value to check + * @return If is a known accession + */ + public static boolean isHGVS(String value) { + // Check regex ':[cnpg].' + return value.contains(":c.") || value.contains(":n.") || value.contains(":p.") || value.contains(":g."); + } + /** * Determines if the given value is a known clinical accession or not. *

diff --git a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/executors/AbstractTwoPhasedVariantQueryExecutor.java b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/executors/AbstractTwoPhasedVariantQueryExecutor.java index a49fe60c3e4..5697998edb1 100644 --- a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/executors/AbstractTwoPhasedVariantQueryExecutor.java +++ b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/executors/AbstractTwoPhasedVariantQueryExecutor.java @@ -133,7 +133,7 @@ protected boolean shouldGetApproximateCount(QueryOptions options, boolean iterat // } protected int getLimit(QueryOptions options) { - return options.getInt(QueryOptions.LIMIT); + return options.getInt(QueryOptions.LIMIT, -1); } protected int getSkip(QueryOptions options) { diff --git a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/search/VariantSearchToVariantConverter.java b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/search/VariantSearchToVariantConverter.java index 1eef2a8ef5e..62841c0a3b9 100644 --- a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/search/VariantSearchToVariantConverter.java +++ b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/search/VariantSearchToVariantConverter.java @@ -34,6 +34,7 @@ import org.opencb.opencga.core.api.ParamConstants; import org.opencb.opencga.core.common.JacksonUtils; import org.opencb.opencga.storage.core.variant.adaptors.VariantField; +import org.opencb.opencga.storage.core.variant.annotation.converters.VariantAnnotationModelUtils; import org.opencb.opencga.storage.core.variant.annotation.converters.VariantTraitAssociationToEvidenceEntryConverter; import org.opencb.opencga.storage.core.variant.query.VariantQueryUtils; import org.slf4j.Logger; @@ -59,6 +60,8 @@ public class VariantSearchToVariantConverter implements ComplexTypeConverter includeFields; + private final VariantAnnotationModelUtils variantAnnotationModelUtils = new VariantAnnotationModelUtils(); + public VariantSearchToVariantConverter() { this.includeFields = null; } @@ -666,19 +669,6 @@ public VariantSearchModel convertToStorageType(Variant variant) { variantSearchModel.setEnd(variant.getEnd()); variantSearchModel.setType(variant.getType().toString()); - // This field contains all possible IDs: id, dbSNP, names, genes, transcripts, protein, clinvar, hpo, ... - // This will help when searching by variant id. This is added at the end of the method after collecting all IDs - Set xrefs = new HashSet<>(); - xrefs.add(variantSearchModel.getId()); - xrefs.add(variantSearchModel.getVariantId()); - if (variant.getNames() != null && !variant.getNames().isEmpty()) { - variant.getNames().forEach(name -> { - if (name != null) { - xrefs.add(name); - } - }); - } - // convert Study related information convertStudies(variant, variantSearchModel, other); @@ -698,11 +688,6 @@ public VariantSearchModel convertToStorageType(Variant variant) { // Process Variant Annotation VariantAnnotation variantAnnotation = variant.getAnnotation(); if (variantAnnotation != null) { - - if (StringUtils.isNotEmpty(variantAnnotation.getId())) { - xrefs.add(variantAnnotation.getId()); - } - // This object will store all info and descriptions for full-text search Set traits = new HashSet<>(); @@ -721,27 +706,6 @@ public VariantSearchModel convertToStorageType(Variant variant) { } variantSearchModel.setRelease(release); - // Add cytoband names - if (variantAnnotation.getCytoband() != null) { - for (Cytoband cytoband : variantAnnotation.getCytoband()) { - xrefs.add(cytoband.getChromosome() + cytoband.getName()); - } - } - - // Add all XRefs coming from the variant annotation - if (variantAnnotation.getXrefs() != null && !variantAnnotation.getXrefs().isEmpty()) { - variantAnnotation.getXrefs().forEach(xref -> { - if (xref != null) { - xrefs.add(xref.getId()); - } - }); - } - - // Add all HGVS coming from the variant annotation - if (ListUtils.isNotEmpty(variantAnnotation.getHgvs())) { - xrefs.addAll(variantAnnotation.getHgvs()); - } - // Set Genes and Consequence Types List consequenceTypes = variantAnnotation.getConsequenceTypes(); if (consequenceTypes != null) { @@ -782,10 +746,6 @@ public VariantSearchModel convertToStorageType(Variant variant) { } } - xrefs.add(gene); - xrefs.add(conseqType.getGeneId()); - xrefs.add(conseqType.getTranscriptId()); - if (StringUtils.isNotEmpty(conseqType.getBiotype())) { biotypes.add(conseqType.getBiotype()); @@ -855,19 +815,16 @@ public VariantSearchModel convertToStorageType(Variant variant) { trans.append(FIELD_SEP); if (StringUtils.isNotEmpty(protVarAnnotation.getUniprotAccession())) { trans.append(protVarAnnotation.getUniprotAccession()); - xrefs.add(protVarAnnotation.getUniprotAccession()); } trans.append(FIELD_SEP); if (StringUtils.isNotEmpty(protVarAnnotation.getUniprotName())) { trans.append(protVarAnnotation.getUniprotName()); - xrefs.add(protVarAnnotation.getUniprotName()); } trans.append(FIELD_SEP); if (StringUtils.isNotEmpty(protVarAnnotation.getUniprotVariantId())) { trans.append(protVarAnnotation.getUniprotVariantId()); - xrefs.add(protVarAnnotation.getUniprotVariantId()); } trans.append(FIELD_SEP).append(protVarAnnotation.getPosition() == null @@ -908,8 +865,6 @@ public VariantSearchModel convertToStorageType(Variant variant) { if (protVarAnnotation.getFeatures() != null) { for (ProteinFeature proteinFeature : protVarAnnotation.getFeatures()) { if (StringUtils.isNotEmpty(proteinFeature.getId())) { - // We store them in xrefs and traits, the number of these IDs is very small - xrefs.add(proteinFeature.getId()); traits.add("PD" + FIELD_SEP + proteinFeature.getId() + FIELD_SEP + proteinFeature.getDescription()); } @@ -992,9 +947,6 @@ public VariantSearchModel convertToStorageType(Variant variant) { List clinical = VariantQueryUtils.buildClinicalCombinations(variantAnnotation); for (EvidenceEntry ev : variantAnnotation.getTraitAssociation()) { if (ev.getSource() != null && StringUtils.isNotEmpty(ev.getSource().getName())) { - if (StringUtils.isNotEmpty(ev.getId())) { - xrefs.add(ev.getId()); - } if ("clinvar".equalsIgnoreCase(ev.getSource().getName())) { String clinSigSuffix = ""; if (ev.getVariantClassification() != null @@ -1064,6 +1016,18 @@ public VariantSearchModel convertToStorageType(Variant variant) { variantSearchModel.setOther(other); } + // This field contains all possible IDs: id, dbSNP, names, genes, transcripts, protein, clinvar, hpo, ... + // This will help when searching by variant id. This is added at the end of the method after collecting all IDs + Set xrefs = variantAnnotationModelUtils.extractXRefs(variant.getAnnotation()); + xrefs.add(variantSearchModel.getId()); + xrefs.add(variantSearchModel.getVariantId()); + if (variant.getNames() != null && !variant.getNames().isEmpty()) { + variant.getNames().forEach(name -> { + if (name != null) { + xrefs.add(name); + } + }); + } variantSearchModel.setXrefs(new ArrayList<>(xrefs)); return variantSearchModel; } diff --git a/opencga-storage/opencga-storage-core/src/test/java/org/opencb/opencga/storage/core/variant/adaptors/VariantDBAdaptorTest.java b/opencga-storage/opencga-storage-core/src/test/java/org/opencb/opencga/storage/core/variant/adaptors/VariantDBAdaptorTest.java index 1f305574a64..010c72b1ea4 100644 --- a/opencga-storage/opencga-storage-core/src/test/java/org/opencb/opencga/storage/core/variant/adaptors/VariantDBAdaptorTest.java +++ b/opencga-storage/opencga-storage-core/src/test/java/org/opencb/opencga/storage/core/variant/adaptors/VariantDBAdaptorTest.java @@ -30,9 +30,7 @@ import org.opencb.biodata.models.variant.Variant; import org.opencb.biodata.models.variant.VariantFileMetadata; import org.opencb.biodata.models.variant.avro.*; -import org.opencb.biodata.models.variant.exceptions.NonStandardCompliantSampleField; import org.opencb.biodata.models.variant.stats.VariantStats; -import org.opencb.biodata.tools.variant.VariantNormalizer; import org.opencb.commons.datastore.core.DataResult; import org.opencb.commons.datastore.core.ObjectMap; import org.opencb.commons.datastore.core.Query; @@ -558,28 +556,45 @@ public void testGetAllVariants_variantId() { @Test public void testGetAllVariants_xref() { - Query query = new Query(ANNOT_XREF.key(), "3:108634973:C:A,rs2032582,HP:0001250,VAR_048225,Q9BY64,ENSG00000250026,TMPRSS11B,COSM1421316"); - queryResult = query(query, null); - assertThat(queryResult, everyResult(allVariantsSummary, anyOf( - hasAnnotation(at("3:108634973:C:A")), - with("id", Variant::getId, is("rs2032582")), - hasAnnotation(with("GeneTraitAssociation", VariantAnnotation::getGeneTraitAssociation, - hasItem(with("HPO", GeneTraitAssociation::getHpo, is("HP:0001250"))))), - hasAnnotation(with("ConsequenceType", VariantAnnotation::getConsequenceTypes, - hasItem(with("ProteinVariantAnnotation", ConsequenceType::getProteinVariantAnnotation, - with("UniprotVariantId", ProteinVariantAnnotation::getUniprotVariantId, is("VAR_048225")))))), - hasAnnotation(with("ConsequenceType", VariantAnnotation::getConsequenceTypes, - hasItem(with("ProteinVariantAnnotation", ConsequenceType::getProteinVariantAnnotation, - with("UniprotName", ProteinVariantAnnotation::getUniprotAccession, is("Q9BY64")))))), - hasAnnotation(with("ConsequenceType", VariantAnnotation::getConsequenceTypes, - hasItem(with("EnsemblGene", ConsequenceType::getGeneId, is("ENSG00000250026"))))), - hasAnnotation(with("ConsequenceType", VariantAnnotation::getConsequenceTypes, - hasItem(with("GeneName", ConsequenceType::getGeneName, is("TMPRSS11B"))))) -// hasAnnotation(with("VariantTraitAssociation", VariantAnnotation::getVariantTraitAssociation, -// with("Cosmic", VariantTraitAssociation::getCosmic, -// hasItem(with("MutationId", Cosmic::getMutationId, is("COSM1421316")))))) - ))); + Map> matchers = new HashMap<>(); + matchers.put("3:108634973:C:A", hasAnnotation(at("3:108634973:C:A"))); + matchers.put("rs2032582", with("id", Variant::getId, is("rs2032582"))); + matchers.put("HP:0001250", hasAnnotation(with("GeneTraitAssociation", VariantAnnotation::getGeneTraitAssociation, + hasItem(with("HPO", GeneTraitAssociation::getHpo, is("HP:0001250")))))); + matchers.put("VAR_048225", hasAnnotation(with("ConsequenceType", VariantAnnotation::getConsequenceTypes, + hasItem(with("ProteinVariantAnnotation", ConsequenceType::getProteinVariantAnnotation, + with("UniprotVariantId", ProteinVariantAnnotation::getUniprotVariantId, is("VAR_048225"))))))); + matchers.put("Q9BY64", hasAnnotation( + with("ConsequenceType", VariantAnnotation::getConsequenceTypes, hasItem( + with("ProteinVariantAnnotation", ConsequenceType::getProteinVariantAnnotation, + with("UniprotAccession", ProteinVariantAnnotation::getUniprotAccession, + is("Q9BY64"))))))); + matchers.put("ENSG00000250026", hasAnnotation( + with("ConsequenceType", VariantAnnotation::getConsequenceTypes, hasItem( + with("GeneId", ConsequenceType::getGeneId, + is("ENSG00000250026")))))); + matchers.put("TMPRSS11B", hasAnnotation( + with("ConsequenceType", VariantAnnotation::getConsequenceTypes, hasItem( + with("GeneName", ConsequenceType::getGeneName, + is("TMPRSS11B")))))); + matchers.put("COSM1421316", hasAnnotation(with("TraitAssociation", VariantAnnotation::getTraitAssociation, hasItem( + with("Cosmic", EvidenceEntry::getId, is("COSM1421316")))))); + + // Query one by one + for (Map.Entry> entry : matchers.entrySet()) { + Query query = new Query(ANNOT_XREF.key(), entry.getKey()); + queryResult = query(query, null); + assertThat(entry.getKey(), queryResult, everyResult(allVariantsSummary, allOf(entry.getValue()))); + query = new Query(ID.key(), entry.getKey()); + queryResult = query(query, null); + assertThat(entry.getKey(), queryResult, everyResult(allVariantsSummary, allOf(entry.getValue()))); + } + + // Query by all xrefs + Query query = new Query(ANNOT_XREF.key(), matchers.keySet()); + queryResult = query(query, null); + assertThat(queryResult, everyResult(allVariantsSummary, anyOf(matchers.values()))); } @Test diff --git a/opencga-storage/opencga-storage-core/src/test/java/org/opencb/opencga/storage/core/variant/query/executors/VariantQueryExecutorTest.java b/opencga-storage/opencga-storage-core/src/test/java/org/opencb/opencga/storage/core/variant/query/executors/VariantQueryExecutorTest.java new file mode 100644 index 00000000000..9da19716cfd --- /dev/null +++ b/opencga-storage/opencga-storage-core/src/test/java/org/opencb/opencga/storage/core/variant/query/executors/VariantQueryExecutorTest.java @@ -0,0 +1,246 @@ +package org.opencb.opencga.storage.core.variant.query.executors; + +import org.hamcrest.Matcher; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Test; +import org.opencb.biodata.models.variant.Variant; +import org.opencb.biodata.models.variant.VariantFileMetadata; +import org.opencb.biodata.models.variant.avro.*; +import org.opencb.commons.datastore.core.ObjectMap; +import org.opencb.commons.datastore.core.Query; +import org.opencb.commons.datastore.core.QueryOptions; +import org.opencb.opencga.core.response.VariantQueryResult; +import org.opencb.opencga.storage.core.StoragePipelineResult; +import org.opencb.opencga.storage.core.exceptions.StorageEngineException; +import org.opencb.opencga.storage.core.metadata.VariantStorageMetadataManager; +import org.opencb.opencga.storage.core.metadata.models.StudyMetadata; +import org.opencb.opencga.storage.core.variant.VariantStorageBaseTest; +import org.opencb.opencga.storage.core.variant.VariantStorageOptions; +import org.opencb.opencga.storage.core.variant.adaptors.GenotypeClass; +import org.opencb.opencga.storage.core.variant.adaptors.VariantDBAdaptor; +import org.opencb.opencga.storage.core.variant.adaptors.VariantQuery; +import org.opencb.opencga.storage.core.variant.adaptors.VariantQueryParam; +import org.opencb.opencga.storage.core.variant.query.ParsedVariantQuery; +import org.opencb.opencga.storage.core.variant.query.VariantQueryUtils; +import org.opencb.opencga.storage.core.variant.query.projection.VariantQueryProjection; +import org.opencb.opencga.storage.core.variant.stats.DefaultVariantStatisticsManager; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.nio.file.Paths; +import java.util.*; + +import static org.hamcrest.CoreMatchers.hasItem; +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.opencb.opencga.storage.core.variant.adaptors.VariantMatchers.*; + +@Ignore +public abstract class VariantQueryExecutorTest extends VariantStorageBaseTest { + + private static Logger logger = LoggerFactory.getLogger(VariantQueryExecutorTest.class); + + protected boolean fileIndexed; + private StudyMetadata studyMetadata; + private VariantFileMetadata fileMetadata; + private int numVariants; + private DBAdaptorVariantQueryExecutor dbQueryExecutor; + private List variantQueryExecutors; + + @Before + public void setUp() throws Exception { + + VariantDBAdaptor dbAdaptor = getVariantStorageEngine().getDBAdaptor(); + VariantStorageMetadataManager metadataManager = dbAdaptor.getMetadataManager(); + if (!fileIndexed) { + studyMetadata = newStudyMetadata(); +// variantSource = new VariantSource(smallInputUri.getPath(), "testAlias", "testStudy", "Study for testing purposes"); + clearDB(DB_NAME); + ObjectMap params = new ObjectMap() + .append(VariantStorageOptions.ASSEMBLY.key(), "GRCH38") + .append(VariantStorageOptions.ANNOTATE.key(), true) + .append(VariantStorageOptions.ANNOTATION_CHECKPOINT_SIZE.key(), 500) + .append(VariantStorageOptions.STATS_CALCULATE.key(), true); + + StoragePipelineResult etlResult = runDefaultETL(smallInputUri, getVariantStorageEngine(), studyMetadata, params); + fileMetadata = variantStorageEngine.getVariantReaderUtils().readVariantFileMetadata(Paths.get(etlResult.getTransformResult().getPath()).toUri()); + numVariants = getExpectedNumLoadedVariants(fileMetadata); + fileIndexed = true; + Integer indexedFileId = metadataManager.getIndexedFiles(studyMetadata.getId()).iterator().next(); + + //Calculate stats + QueryOptions options = new QueryOptions(VariantStorageOptions.STUDY.key(), STUDY_NAME) + .append(VariantStorageOptions.LOAD_BATCH_SIZE.key(), 100) + .append(DefaultVariantStatisticsManager.OUTPUT, outputUri) + .append(DefaultVariantStatisticsManager.OUTPUT_FILE_NAME, "cohort1.cohort2.stats"); + Iterator iterator = metadataManager.getFileMetadata(studyMetadata.getId(), indexedFileId).getSamples().iterator(); + + /** Create cohorts **/ + HashSet cohort1 = new HashSet<>(); + cohort1.add(metadataManager.getSampleName(studyMetadata.getId(), iterator.next())); + cohort1.add(metadataManager.getSampleName(studyMetadata.getId(), iterator.next())); + + HashSet cohort2 = new HashSet<>(); + cohort2.add(metadataManager.getSampleName(studyMetadata.getId(), iterator.next())); + cohort2.add(metadataManager.getSampleName(studyMetadata.getId(), iterator.next())); + + Map> cohorts = new HashMap<>(); + cohorts.put("cohort1", cohort1); + cohorts.put("cohort2", cohort2); + metadataManager.registerCohorts(studyMetadata.getName(), cohorts); + + variantStorageEngine.calculateStats(studyMetadata.getName(), + new ArrayList<>(cohorts.keySet()), options); + + + variantQueryExecutors = variantStorageEngine.getVariantQueryExecutors(); + dbQueryExecutor = null; + for (VariantQueryExecutor variantQueryExecutor : variantQueryExecutors) { + if (variantQueryExecutor instanceof DBAdaptorVariantQueryExecutor) { + dbQueryExecutor = (DBAdaptorVariantQueryExecutor) variantQueryExecutor; + break; + } + } + Assert.assertNotNull(dbQueryExecutor); + } + } + + @Test + public void testXRefRs() throws StorageEngineException { + Map> matchers = new LinkedHashMap<>(); + matchers.put("3:108634973:C:A", hasAnnotation(at("3:108634973:C:A"))); +// matchers.put("rs2032582", with("id", Variant::getId, is("rs2032582"))); + matchers.put("HP:0001250", hasAnnotation(with("GeneTraitAssociation", VariantAnnotation::getGeneTraitAssociation, + hasItem(with("HPO", GeneTraitAssociation::getHpo, is("HP:0001250")))))); + matchers.put("VAR_031174", hasAnnotation(with("ConsequenceType", VariantAnnotation::getConsequenceTypes, + hasItem(with("ProteinVariantAnnotation", ConsequenceType::getProteinVariantAnnotation, + with("UniprotVariantId", ProteinVariantAnnotation::getUniprotVariantId, is("VAR_031174"))))))); +// matchers.put("Q9BY64", hasAnnotation( +// with("ConsequenceType", VariantAnnotation::getConsequenceTypes, hasItem( +// with("ProteinVariantAnnotation", ConsequenceType::getProteinVariantAnnotation, +// with("UniprotAccession", ProteinVariantAnnotation::getUniprotAccession, +// is("Q9BY64"))))))); + matchers.put("ENSG00000170925", hasAnnotation( + with("ConsequenceType", VariantAnnotation::getConsequenceTypes, hasItem( + with("GeneId", ConsequenceType::getGeneId, + is("ENSG00000170925")))))); + matchers.put("TEX13B", hasAnnotation( + with("ConsequenceType", VariantAnnotation::getConsequenceTypes, hasItem( + with("GeneName", ConsequenceType::getGeneName, + is("TEX13B")))))); + matchers.put("COSV60260399", hasAnnotation(with("TraitAssociation", VariantAnnotation::getTraitAssociation, hasItem( + with("Cosmic", EvidenceEntry::getId, is("COSV60260399")))))); + matchers.put("ENST00000341832.11(ENSG00000248333):c.356-1170A>G", hasAnnotation(with("HGVS", VariantAnnotation::getHgvs, hasItem( + is("ENST00000341832.11(ENSG00000248333):c.356-1170A>G"))))); + + for (Map.Entry> entry : matchers.entrySet()) { + testQuery(new VariantQuery().xref(entry.getKey()), new QueryOptions(), entry.getValue()); + VariantQueryResult result = testQuery(new VariantQuery().xref(entry.getKey()) + .study(studyMetadata.getName()) + .includeSampleId(true) + .includeSampleAll(), new QueryOptions(), entry.getValue()); + if (result.getNumResults() == 1) { + for (SampleEntry sample : result.first().getStudies().get(0).getSamples()) { + if (GenotypeClass.MAIN_ALT.test(sample.getData().get(0))) { + testQuery(new VariantQuery().xref(entry.getKey()) + .study(studyMetadata.getName()) + .includeSampleId(true) + .sample(sample.getSampleId()), + new QueryOptions(), entry.getValue()); + } + } + } else { + List samples = result.first().getStudies().get(0).getOrderedSamplesName(); + testQuery(new VariantQuery().xref(entry.getKey()) + .study(studyMetadata.getName()) + .includeSampleId(true) + .sample(samples), + new QueryOptions(), entry.getValue()); + } +// Variant v = result.first(); +// +// for (SampleEntry sample : v.getStudies().get(0).getSamples()) { +// if (GenotypeClass.MAIN_ALT.test(sample.getData().get(0))) { +// testQuery(new VariantQuery().xref(entry.getKey()) +// .study(studyMetadata.getName()) +// .includeSampleId(true) +// .sample(sample.getSampleId()), +// new QueryOptions(), entry.getValue()); +// } +// } + } + } + + public VariantQueryResult testQuery(Query query, QueryOptions options, Matcher matcher) throws StorageEngineException { + logger.info(""); + logger.info(""); + logger.info("####################################################"); + logger.info("########## Testing query " + query.toJson()); + logger.info("####################################################"); + Assert.assertTrue(dbQueryExecutor.canUseThisExecutor(query, options)); + + ParsedVariantQuery variantQuery = variantStorageEngine.parseQuery(query, options); + VariantQueryResult expected = dbQueryExecutor.get(new Query(variantQuery.getQuery()), new QueryOptions(options)); + + VariantQueryResult unfilteredResult = null; + VariantQueryResult result = null; + if (matcher != null) { + Query emptyQuery = new Query(); + List fileNames = new LinkedList<>(); + List sampleNames = new LinkedList<>(); + List studyNames = new LinkedList<>(); + emptyQuery.put(VariantQueryParam.INCLUDE_FILE.key(), VariantQueryUtils.NONE); + emptyQuery.put(VariantQueryParam.INCLUDE_SAMPLE.key(), VariantQueryUtils.NONE); + emptyQuery.put(VariantQueryParam.INCLUDE_STUDY.key(), VariantQueryUtils.NONE); + emptyQuery.putIfNotNull(VariantQueryParam.INCLUDE_SAMPLE_ID.key(), query.get(VariantQueryParam.INCLUDE_SAMPLE_ID.key())); + emptyQuery.putIfNotNull(VariantQueryParam.INCLUDE_GENOTYPE.key(), query.get(VariantQueryParam.INCLUDE_GENOTYPE.key())); + emptyQuery.putIfNotNull(VariantQueryParam.INCLUDE_SAMPLE_DATA.key(), query.get(VariantQueryParam.INCLUDE_SAMPLE_DATA.key())); + for (VariantQueryProjection.StudyVariantQueryProjection study : variantQuery.getProjection().getStudies().values()) { + studyNames.add(study.getStudyMetadata().getName()); + for (Integer file : study.getFiles()) { + String fileName = metadataManager.getFileName(study.getStudyMetadata().getId(), file); + fileNames.add(fileName); + } + for (Integer sample : study.getSamples()) { + String sampleName = metadataManager.getSampleName(study.getStudyMetadata().getId(), sample); + sampleNames.add(sampleName); + } + } + if (!studyNames.isEmpty()) { + emptyQuery.put(VariantQueryParam.INCLUDE_STUDY.key(), studyNames); + } + if (!fileNames.isEmpty()) { + emptyQuery.put(VariantQueryParam.INCLUDE_FILE.key(), fileNames); + } + if (!sampleNames.isEmpty()) { + emptyQuery.put(VariantQueryParam.INCLUDE_SAMPLE.key(), sampleNames); + } + QueryOptions emptyOptions = new QueryOptions(); + emptyOptions.putIfNotEmpty(QueryOptions.INCLUDE, options.getString(QueryOptions.INCLUDE)); + emptyOptions.putIfNotEmpty(QueryOptions.EXCLUDE, options.getString(QueryOptions.EXCLUDE)); + unfilteredResult = dbQueryExecutor.get(emptyQuery, emptyOptions); + } + + for (VariantQueryExecutor variantQueryExecutor : variantQueryExecutors) { + if (variantQueryExecutor.canUseThisExecutor(query, options)) { + logger.info("##########################"); + logger.info("########## Testing " + variantQueryExecutor.getClass().getSimpleName() + " with query " + query.toJson()); + result = variantQueryExecutor.get(new Query(variantQuery.getQuery()), new QueryOptions(options)); + logger.info("########## Num results : " + result.getNumResults()); + logger.info("##########################"); + Assert.assertEquals(expected.getResults(), result.getResults()); + + assertThat(result, numResults(gt(0))); + + if (matcher != null) { + assertThat(result, everyResult(unfilteredResult, matcher)); + } + } + } + // Return any result. + return result; + } + +} diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/converters/annotation/VariantAnnotationToPhoenixConverter.java b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/converters/annotation/VariantAnnotationToPhoenixConverter.java index c9bb8646c04..d991c8a3c30 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/converters/annotation/VariantAnnotationToPhoenixConverter.java +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/converters/annotation/VariantAnnotationToPhoenixConverter.java @@ -16,7 +16,6 @@ package org.opencb.opencga.storage.hadoop.variant.converters.annotation; -import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.StringUtils; import org.apache.hadoop.hbase.client.Put; import org.apache.hadoop.hbase.util.Bytes; @@ -24,6 +23,7 @@ import org.opencb.biodata.models.variant.avro.*; import org.opencb.biodata.tools.commons.Converter; import org.opencb.commons.utils.CompressionUtils; +import org.opencb.opencga.storage.core.variant.annotation.converters.VariantAnnotationModelUtils; import org.opencb.opencga.storage.core.variant.query.VariantQueryUtils; import org.opencb.opencga.storage.hadoop.variant.adaptors.phoenix.PhoenixHelper; import org.opencb.opencga.storage.hadoop.variant.adaptors.phoenix.VariantPhoenixSchema; @@ -62,6 +62,7 @@ public class VariantAnnotationToPhoenixConverter extends AbstractPhoenixConverte } private int annotationId; + private VariantAnnotationModelUtils variantAnnotationModelUtils = new VariantAnnotationModelUtils(); @Deprecated public VariantAnnotationToPhoenixConverter(byte[] columnFamily) { @@ -114,10 +115,6 @@ public VariantAnnotationToPhoenixConverter(byte[] columnFamily, int annotationId // Set hpo = new HashSet<>(); Set drugs = new HashSet<>(); Set proteinKeywords = new HashSet<>(); - // Contains all the xrefs, and the id, the geneNames and transcripts - Set xrefs = new HashSet<>(); - - addNotNull(xrefs, variantAnnotation.getId()); List consequenceTypes = variantAnnotation.getConsequenceTypes() == null ? Collections.emptyList() @@ -125,7 +122,9 @@ public VariantAnnotationToPhoenixConverter(byte[] columnFamily, int annotationId for (ConsequenceType consequenceType : consequenceTypes) { addNotNull(genes, consequenceType.getGeneName()); addNotNull(genes, consequenceType.getGeneId()); + addNotNull(genes, consequenceType.getEnsemblGeneId()); addNotNull(transcripts, consequenceType.getTranscriptId()); + addNotNull(transcripts, consequenceType.getEnsemblTranscriptId()); addNotNull(biotype, consequenceType.getBiotype()); addAllNotNull(flags, consequenceType.getTranscriptFlags()); @@ -192,32 +191,14 @@ public VariantAnnotationToPhoenixConverter(byte[] columnFamily, int annotationId if (proteinVariantAnnotation.getKeywords() != null) { proteinKeywords.addAll(proteinVariantAnnotation.getKeywords()); } - addNotNull(xrefs, proteinVariantAnnotation.getUniprotName()); - addNotNull(xrefs, proteinVariantAnnotation.getUniprotAccession()); - addNotNull(xrefs, proteinVariantAnnotation.getUniprotVariantId()); } } - if (CollectionUtils.isNotEmpty(variantAnnotation.getTraitAssociation())) { - for (EvidenceEntry evidenceEntry : variantAnnotation.getTraitAssociation()) { - addNotNull(xrefs, evidenceEntry.getId()); - } - } - - xrefs.addAll(genes); - xrefs.addAll(transcripts); - if (variantAnnotation.getXrefs() != null) { - for (Xref xref : variantAnnotation.getXrefs()) { - addNotNull(xrefs, xref.getId()); - } - } if (variantAnnotation.getGeneTraitAssociation() != null) { for (GeneTraitAssociation geneTrait : variantAnnotation.getGeneTraitAssociation()) { addNotNull(geneTraitName, geneTrait.getName()); addNotNull(geneTraitId, geneTrait.getId()); - addNotNull(xrefs, geneTrait.getHpo()); - addNotNull(xrefs, geneTrait.getId()); } } @@ -235,6 +216,8 @@ public VariantAnnotationToPhoenixConverter(byte[] columnFamily, int annotationId geneSoFlag.remove(null); soFlag.remove(null); + Set xrefs = variantAnnotationModelUtils.extractXRefs(variantAnnotation); + map.put(CHROMOSOME, variantAnnotation.getChromosome()); map.put(POSITION, variantAnnotation.getStart()); map.put(REFERENCE, variantAnnotation.getReference()); diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/index/SampleIndexVariantQueryExecutor.java b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/index/SampleIndexVariantQueryExecutor.java index 64cf8669153..2e1b74b9f88 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/index/SampleIndexVariantQueryExecutor.java +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/index/SampleIndexVariantQueryExecutor.java @@ -131,7 +131,9 @@ protected Object getOrIterator(Query query, QueryOptions inputOptions, boolean i // Ensure results are sorted and it's not counting from variants dbAdaptor options.put(QueryOptions.SORT, true); options.put(QueryOptions.COUNT, false); - options.put(QueryOptions.LIMIT, tmpLimit); + if (limit > 0) { + options.put(QueryOptions.LIMIT, tmpLimit); + } MultiVariantDBIterator variantDBIterator = dbAdaptor.iterator( new org.opencb.opencga.storage.core.variant.adaptors.iterators.DelegatedVariantDBIterator(variants) { @@ -166,7 +168,7 @@ public void close() throws Exception { } // Ensure limit - if (result.getNumResults() > limit) { + if (limit > 0 && result.getNumResults() > limit) { result.setResults(result.getResults().subList(0, limit)); result.setNumResults(limit); } diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/test/java/org/opencb/opencga/storage/hadoop/variant/query/executors/HadoopVariantQueryExecutorTest.java b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/test/java/org/opencb/opencga/storage/hadoop/variant/query/executors/HadoopVariantQueryExecutorTest.java new file mode 100644 index 00000000000..7cc495bbe63 --- /dev/null +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/test/java/org/opencb/opencga/storage/hadoop/variant/query/executors/HadoopVariantQueryExecutorTest.java @@ -0,0 +1,30 @@ +package org.opencb.opencga.storage.hadoop.variant.query.executors; + +import org.junit.Before; +import org.junit.ClassRule; +import org.junit.experimental.categories.Category; +import org.junit.rules.ExternalResource; +import org.opencb.opencga.core.testclassification.duration.LongTests; +import org.opencb.opencga.storage.core.variant.query.executors.VariantQueryExecutorTest; +import org.opencb.opencga.storage.hadoop.variant.HadoopVariantStorageTest; +import org.opencb.opencga.storage.hadoop.variant.VariantHbaseTestUtils; + +import static org.opencb.opencga.storage.hadoop.variant.VariantHbaseTestUtils.printVariants; + + +@Category(LongTests.class) +public class HadoopVariantQueryExecutorTest extends VariantQueryExecutorTest implements HadoopVariantStorageTest { + + @ClassRule + public static ExternalResource externalResource = new HadoopExternalResource(); + + @Override + @Before + public void setUp() throws Exception { + boolean firstRun = !super.fileIndexed; + super.setUp(); + if (firstRun) { + VariantHbaseTestUtils.printVariants(getVariantStorageEngine().getDBAdaptor(), newOutputUri()); + } + } +} From 9d315933453c6f9d392ab08b213da76d8c4fa4fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacobo=20Coll=20Morag=C3=B3n?= Date: Wed, 10 Apr 2024 16:26:44 +0100 Subject: [PATCH 22/85] storage: Identify ProteinFeatureID as an xref #TASK-5878 --- .../variant/adaptors/VariantQueryParam.java | 2 +- .../VariantAnnotationModelUtils.java | 8 --- .../variant/query/VariantQueryParser.java | 6 +- .../core/variant/query/VariantQueryUtils.java | 15 +++++ .../executors/VariantQueryExecutorTest.java | 60 ++++++++++++------- .../solr/VariantSolrExternalResource.java | 1 + 6 files changed, 62 insertions(+), 30 deletions(-) diff --git a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/adaptors/VariantQueryParam.java b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/adaptors/VariantQueryParam.java index f2d03ba6ddb..c10fd5def09 100644 --- a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/adaptors/VariantQueryParam.java +++ b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/adaptors/VariantQueryParam.java @@ -41,7 +41,7 @@ public final class VariantQueryParam implements QueryParam { private static final String ACCEPTS_AND_OR = "Accepts AND (" + AND + ") and OR (" + OR + ") operators."; public static final String ID_DESCR - = "List of IDs, these can be rs IDs (dbSNP) or variants in the format chrom:start:ref:alt, e.g. rs116600158,19:7177679:C:T"; + = "List of variant IDs in the format chrom:start:ref:alt, e.g. 19:7177679:C:T"; public static final VariantQueryParam ID = new VariantQueryParam("id", TEXT_ARRAY, ID_DESCR); public static final String REGION_DESCR diff --git a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/annotation/converters/VariantAnnotationModelUtils.java b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/annotation/converters/VariantAnnotationModelUtils.java index cb317120362..c31b7137236 100644 --- a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/annotation/converters/VariantAnnotationModelUtils.java +++ b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/annotation/converters/VariantAnnotationModelUtils.java @@ -14,7 +14,6 @@ public class VariantAnnotationModelUtils { * Includes: * - annotation.id * - annotation.xrefs.id - * - annotation.cytoband.chromosome + cytoband.name * - annotation.hgvs * - annotation.consequenceTypes.geneName * - annotation.consequenceTypes.geneId @@ -50,13 +49,6 @@ public Set extractXRefs(VariantAnnotation variantAnnotation) { } } - if (variantAnnotation.getCytoband() != null) { - for (Cytoband cytoband : variantAnnotation.getCytoband()) { - // TODO: Why do we need to add the chromosome name? - xrefs.add(cytoband.getChromosome() + cytoband.getName()); - } - } - if (variantAnnotation.getHgvs() != null) { xrefs.addAll(variantAnnotation.getHgvs()); } diff --git a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/VariantQueryParser.java b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/VariantQueryParser.java index 21c1124c88e..c28e76eab24 100644 --- a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/VariantQueryParser.java +++ b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/VariantQueryParser.java @@ -851,7 +851,11 @@ public static ParsedVariantQuery.VariantQueryXref parseXrefs(Query query) { if (variant != null) { xrefs.getVariants().add(variant); } else { - if (isVariantAccession(value) || isClinicalAccession(value) || isGeneAccession(value) || isHGVS(value)) { + if (isVariantAccession(value) + || isClinicalAccession(value) + || isGeneAccession(value) + || isHGVS(value) + || isProteinFeatureId(value)) { xrefs.getOtherXrefs().add(value); } else { genes.add(value); diff --git a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/VariantQueryUtils.java b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/VariantQueryUtils.java index c11c3f64634..371b7b3239a 100644 --- a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/VariantQueryUtils.java +++ b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/VariantQueryUtils.java @@ -474,6 +474,9 @@ public static boolean isVariantAccession(String value) { */ public static boolean isHGVS(String value) { // Check regex ':[cnpg].' + // HGVC examples : + // - "1:g.65325832G>A" + // - "1:g.65325832_65325833insA" return value.contains(":c.") || value.contains(":n.") || value.contains(":p.") || value.contains(":g."); } @@ -505,6 +508,18 @@ public static boolean isGeneAccession(String value) { return isHpo(value) || value.startsWith("OMIM:") || value.startsWith("umls:"); } + /** + * Determines if the given value is a valid protein feature id. + *

+ * Protein feature id starts with 'PRO_', 'VAR_' or 'VSP_' + * + * @param value Value to check + * @return If is a known accession + */ + public static boolean isProteinFeatureId(String value) { + return value.startsWith("PRO_") | value.startsWith("VAR_") | value.startsWith("VSP_"); + } + /** * Determines if the given value is a HPO term or not. *

diff --git a/opencga-storage/opencga-storage-core/src/test/java/org/opencb/opencga/storage/core/variant/query/executors/VariantQueryExecutorTest.java b/opencga-storage/opencga-storage-core/src/test/java/org/opencb/opencga/storage/core/variant/query/executors/VariantQueryExecutorTest.java index 9da19716cfd..b5fdde0fb85 100644 --- a/opencga-storage/opencga-storage-core/src/test/java/org/opencb/opencga/storage/core/variant/query/executors/VariantQueryExecutorTest.java +++ b/opencga-storage/opencga-storage-core/src/test/java/org/opencb/opencga/storage/core/variant/query/executors/VariantQueryExecutorTest.java @@ -1,10 +1,7 @@ package org.opencb.opencga.storage.core.variant.query.executors; import org.hamcrest.Matcher; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Ignore; -import org.junit.Test; +import org.junit.*; import org.opencb.biodata.models.variant.Variant; import org.opencb.biodata.models.variant.VariantFileMetadata; import org.opencb.biodata.models.variant.avro.*; @@ -25,6 +22,7 @@ import org.opencb.opencga.storage.core.variant.query.ParsedVariantQuery; import org.opencb.opencga.storage.core.variant.query.VariantQueryUtils; import org.opencb.opencga.storage.core.variant.query.projection.VariantQueryProjection; +import org.opencb.opencga.storage.core.variant.solr.VariantSolrExternalResource; import org.opencb.opencga.storage.core.variant.stats.DefaultVariantStatisticsManager; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -49,11 +47,15 @@ public abstract class VariantQueryExecutorTest extends VariantStorageBaseTest { private DBAdaptorVariantQueryExecutor dbQueryExecutor; private List variantQueryExecutors; + @ClassRule + public static VariantSolrExternalResource solr = new VariantSolrExternalResource(); + @Before public void setUp() throws Exception { VariantDBAdaptor dbAdaptor = getVariantStorageEngine().getDBAdaptor(); VariantStorageMetadataManager metadataManager = dbAdaptor.getMetadataManager(); + solr.configure(variantStorageEngine); if (!fileIndexed) { studyMetadata = newStudyMetadata(); // variantSource = new VariantSource(smallInputUri.getPath(), "testAlias", "testStudy", "Study for testing purposes"); @@ -94,6 +96,9 @@ public void setUp() throws Exception { variantStorageEngine.calculateStats(studyMetadata.getName(), new ArrayList<>(cohorts.keySet()), options); + solr.configure(variantStorageEngine); + variantStorageEngine.secondaryIndex(); + Assert.assertTrue(variantStorageEngine.secondaryAnnotationIndexActiveAndAlive()); variantQueryExecutors = variantStorageEngine.getVariantQueryExecutors(); dbQueryExecutor = null; @@ -134,6 +139,21 @@ public void testXRefRs() throws StorageEngineException { with("Cosmic", EvidenceEntry::getId, is("COSV60260399")))))); matchers.put("ENST00000341832.11(ENSG00000248333):c.356-1170A>G", hasAnnotation(with("HGVS", VariantAnnotation::getHgvs, hasItem( is("ENST00000341832.11(ENSG00000248333):c.356-1170A>G"))))); + matchers.put("VSP_039324", hasAnnotation( + with("ConsequenceType", VariantAnnotation::getConsequenceTypes, + hasItem(with("ProteinVariantAnnotation", ConsequenceType::getProteinVariantAnnotation, + with("Features", ProteinVariantAnnotation::getFeatures, + hasItem(with("id", ProteinFeature::getId, is("VSP_039324"))))))))); + matchers.put("VAR_081776", hasAnnotation( + with("ConsequenceType", VariantAnnotation::getConsequenceTypes, + hasItem(with("ProteinVariantAnnotation", ConsequenceType::getProteinVariantAnnotation, + with("Features", ProteinVariantAnnotation::getFeatures, + hasItem(with("id", ProteinFeature::getId, is("VAR_081776"))))))))); + matchers.put("PRO_0000211180", hasAnnotation( + with("ConsequenceType", VariantAnnotation::getConsequenceTypes, + hasItem(with("ProteinVariantAnnotation", ConsequenceType::getProteinVariantAnnotation, + with("Features", ProteinVariantAnnotation::getFeatures, + hasItem(with("id", ProteinFeature::getId, is("PRO_0000211180"))))))))); for (Map.Entry> entry : matchers.entrySet()) { testQuery(new VariantQuery().xref(entry.getKey()), new QueryOptions(), entry.getValue()); @@ -159,17 +179,6 @@ public void testXRefRs() throws StorageEngineException { .sample(samples), new QueryOptions(), entry.getValue()); } -// Variant v = result.first(); -// -// for (SampleEntry sample : v.getStudies().get(0).getSamples()) { -// if (GenotypeClass.MAIN_ALT.test(sample.getData().get(0))) { -// testQuery(new VariantQuery().xref(entry.getKey()) -// .study(studyMetadata.getName()) -// .includeSampleId(true) -// .sample(sample.getSampleId()), -// new QueryOptions(), entry.getValue()); -// } -// } } } @@ -177,8 +186,15 @@ public VariantQueryResult testQuery(Query query, QueryOptions options, logger.info(""); logger.info(""); logger.info("####################################################"); - logger.info("########## Testing query " + query.toJson()); + logger.info("########## TEST QUERY :" + query.toJson()); logger.info("####################################################"); + logger.info("## Allowed VariantQueryExecutors:"); + for (VariantQueryExecutor variantQueryExecutor : variantQueryExecutors) { + if (variantQueryExecutor.canUseThisExecutor(query, options)) { + logger.info("## - " + variantQueryExecutor.getClass().getSimpleName()); + } + } + logger.info("## Using DBAdaptorVariantQueryExecutor for expected results"); Assert.assertTrue(dbQueryExecutor.canUseThisExecutor(query, options)); ParsedVariantQuery variantQuery = variantStorageEngine.parseQuery(query, options); @@ -187,6 +203,7 @@ public VariantQueryResult testQuery(Query query, QueryOptions options, VariantQueryResult unfilteredResult = null; VariantQueryResult result = null; if (matcher != null) { + logger.info("## Unfiltered query for comparison"); Query emptyQuery = new Query(); List fileNames = new LinkedList<>(); List sampleNames = new LinkedList<>(); @@ -225,11 +242,14 @@ public VariantQueryResult testQuery(Query query, QueryOptions options, for (VariantQueryExecutor variantQueryExecutor : variantQueryExecutors) { if (variantQueryExecutor.canUseThisExecutor(query, options)) { - logger.info("##########################"); - logger.info("########## Testing " + variantQueryExecutor.getClass().getSimpleName() + " with query " + query.toJson()); + logger.info(""); + logger.info("###################"); + logger.info("### Testing " + variantQueryExecutor.getClass().getSimpleName()); result = variantQueryExecutor.get(new Query(variantQuery.getQuery()), new QueryOptions(options)); - logger.info("########## Num results : " + result.getNumResults()); - logger.info("##########################"); + logger.info("### Num results : " + result.getNumResults()); + logger.info("###################"); + expected.getResults().sort(Comparator.comparing(Variant::toString)); + result.getResults().sort(Comparator.comparing(Variant::toString)); Assert.assertEquals(expected.getResults(), result.getResults()); assertThat(result, numResults(gt(0))); diff --git a/opencga-storage/opencga-storage-core/src/test/java/org/opencb/opencga/storage/core/variant/solr/VariantSolrExternalResource.java b/opencga-storage/opencga-storage-core/src/test/java/org/opencb/opencga/storage/core/variant/solr/VariantSolrExternalResource.java index 7ae1991221d..03548c65102 100644 --- a/opencga-storage/opencga-storage-core/src/test/java/org/opencb/opencga/storage/core/variant/solr/VariantSolrExternalResource.java +++ b/opencga-storage/opencga-storage-core/src/test/java/org/opencb/opencga/storage/core/variant/solr/VariantSolrExternalResource.java @@ -120,6 +120,7 @@ public VariantSearchManager configure(VariantStorageEngine variantStorageEngine) VariantSearchManager variantSearchManager = variantStorageEngine.getVariantSearchManager(); variantSearchManager.setSolrManager(new SolrManager(solrClient, "localhost", "core", variantStorageEngine.getConfiguration().getSearch().getTimeout())); + variantSearchManager.setSolrClient(solrClient); return variantSearchManager; } From 4caa913179fbe37d6b97a2bca6a618e60f0b1112 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacobo=20Coll=20Morag=C3=B3n?= Date: Fri, 12 Apr 2024 14:15:31 +0100 Subject: [PATCH 23/85] storage: Fix rs-id filtering in sample/data endpoint #TASK-5878 --- .../storage/core/utils/CellBaseUtils.java | 1 + .../core/variant/VariantStorageEngine.java | 32 +++++++++++++++++-- .../sample/VariantSampleDataManager.java | 12 +++---- .../variant/adaptors/VariantMatchers.java | 14 ++++++++ .../annotation/DummyTestAnnotator.java | 7 ++++ .../VariantAnnotationManagerTest.java | 5 +++ .../variant/HadoopVariantStorageEngine.java | 6 ++-- .../sample/HBaseVariantSampleDataManager.java | 20 +++--------- 8 files changed, 70 insertions(+), 27 deletions(-) diff --git a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/utils/CellBaseUtils.java b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/utils/CellBaseUtils.java index ed0848a0e0b..f8dfc2d1f9f 100644 --- a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/utils/CellBaseUtils.java +++ b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/utils/CellBaseUtils.java @@ -343,6 +343,7 @@ public List getVariants(List variantsStr) { List variants = new ArrayList<>(variantsStr.size()); List> response = null; try { + // FIXME: This method should call genomic/variant/snp/search response = checkNulls(cellBaseClient.getVariantClient().get(variantsStr, new QueryOptions(QueryOptions.INCLUDE, VariantField.CHROMOSOME.fieldName() + "," diff --git a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/VariantStorageEngine.java b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/VariantStorageEngine.java index a3ab7e539b5..018d09292f1 100644 --- a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/VariantStorageEngine.java +++ b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/VariantStorageEngine.java @@ -1192,8 +1192,36 @@ public VariantQueryResult getCompoundHeterozygous(String study, String return get(query, options); } - public DataResult getSampleData(String variant, String study, QueryOptions options) throws StorageEngineException { - return new VariantSampleDataManager(getDBAdaptor()).getSampleData(variant, study, options); + public DataResult getSampleData(String variantStr, String study, QueryOptions options) throws StorageEngineException { + final Variant variant = getVariant(variantStr); + return getVariantSampleDataManager().getSampleData(variant, study, options); + } + + public Variant getVariant(String variantStr) { + final Variant variant; + if (VariantQueryUtils.isVariantId(variantStr)) { + variant = new Variant(variantStr); + } else if (VariantQueryUtils.isVariantAccession(variantStr)) { + VariantQueryResult result = get(new Query(VariantQueryParam.ANNOT_XREF.key(), variantStr), + new QueryOptions(QueryOptions.INCLUDE, VariantField.ID).append(QueryOptions.LIMIT, 1).append(QueryOptions.COUNT, true)); + if (result.getNumMatches() > 1) { + throw new VariantQueryException("Not unique variant identifier '" + variantStr + "'." + + " Found " + result.getNumMatches() + " results"); + } else if (result.getNumResults() == 1) { + variant = result.first(); + } else { + throw VariantQueryException.variantNotFound(variantStr); + } + } else { + throw new VariantQueryException("Variant not valid. Variant = '" + variantStr + "'. Supported values:" + + " {chr}:{start}:{end}:{ref}:{alt}, rs{id}"); + } + variant.setId(variant.toString()); + return variant; + } + + protected VariantSampleDataManager getVariantSampleDataManager() throws StorageEngineException { + return new VariantSampleDataManager(getDBAdaptor()); } public VariantQueryResult get(Query query, QueryOptions options) { diff --git a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/adaptors/sample/VariantSampleDataManager.java b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/adaptors/sample/VariantSampleDataManager.java index d0e09c582e5..b575d1f63e5 100644 --- a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/adaptors/sample/VariantSampleDataManager.java +++ b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/adaptors/sample/VariantSampleDataManager.java @@ -40,13 +40,13 @@ public VariantSampleDataManager(VariantDBAdaptor dbAdaptor) { } - public final DataResult getSampleData(String variant, String study, QueryOptions options) { + public final DataResult getSampleData(Variant variant, String study, QueryOptions options) { options = options == null ? new QueryOptions() : options; int sampleLimit = options.getInt(SAMPLE_BATCH_SIZE, SAMPLE_BATCH_SIZE_DEFAULT); return getSampleData(variant, study, options, sampleLimit); } - public final DataResult getSampleData(String variant, String study, QueryOptions options, int sampleLimit) { + public final DataResult getSampleData(Variant variant, String study, QueryOptions options, int sampleLimit) { options = options == null ? new QueryOptions() : options; @@ -77,7 +77,7 @@ public final DataResult getSampleData(String variant, String study, Que } protected DataResult getSampleData( - String variantStr, String study, QueryOptions options, List includeSamples, Set genotypes, + Variant variant, String study, QueryOptions options, List includeSamples, Set genotypes, int sampleLimit) { options = options == null ? new QueryOptions() : options; Set includeFields = VariantField.getIncludeFields(options); @@ -98,7 +98,7 @@ protected DataResult getSampleData( int queries = 0; while (true) { queries++; - Query query = new Query(VariantQueryParam.ID.key(), variantStr) + Query query = new Query(VariantQueryParam.ID.key(), variant.toString()) .append(VariantQueryParam.STUDY.key(), study) .append(VariantQueryParam.INCLUDE_GENOTYPE.key(), options.get(VariantQueryParam.INCLUDE_GENOTYPE.key())) .append(VariantQueryParam.INCLUDE_SAMPLE_DATA.key(), options.get(VariantQueryParam.INCLUDE_SAMPLE_DATA.key())) @@ -130,7 +130,7 @@ protected DataResult getSampleData( DataResult result = dbAdaptor.get(query, variantQueryOptions); if (result.getNumResults() == 0) { - throw VariantQueryException.variantNotFound(variantStr); + throw VariantQueryException.variantNotFound(variant.toString()); } dbTime += result.getTime(); Variant partialVariant = result.first(); @@ -199,7 +199,7 @@ protected DataResult getSampleData( } } - Variant variant = new Variant(variantStr); + variant = new Variant(variant.toString()); variant.setAnnotation(annotation); StudyEntry studyEntry = new StudyEntry(study); variant.addStudyEntry(studyEntry); diff --git a/opencga-storage/opencga-storage-core/src/test/java/org/opencb/opencga/storage/core/variant/adaptors/VariantMatchers.java b/opencga-storage/opencga-storage-core/src/test/java/org/opencb/opencga/storage/core/variant/adaptors/VariantMatchers.java index 7f790ffe609..11c9a6f8927 100644 --- a/opencga-storage/opencga-storage-core/src/test/java/org/opencb/opencga/storage/core/variant/adaptors/VariantMatchers.java +++ b/opencga-storage/opencga-storage-core/src/test/java/org/opencb/opencga/storage/core/variant/adaptors/VariantMatchers.java @@ -139,6 +139,20 @@ public static Matcher overlaps(Variant variant) { return overlaps(new Region(variant.getChromosome(), variant.getStart(), variant.getEnd()), true); } + public static Matcher samePosition(Variant variant) { + return new TypeSafeDiagnosingMatcher() { + @Override + protected boolean matchesSafely(Variant item, Description mismatchDescription) { + return variant.sameGenomicVariant(item); + } + + @Override + public void describeTo(Description description) { + description.appendText("has same genomic region " + variant); + } + }; + } + public static Matcher overlaps(Region region) { return overlaps(region, true); } diff --git a/opencga-storage/opencga-storage-core/src/test/java/org/opencb/opencga/storage/core/variant/annotation/DummyTestAnnotator.java b/opencga-storage/opencga-storage-core/src/test/java/org/opencb/opencga/storage/core/variant/annotation/DummyTestAnnotator.java index b36e8fa90ad..8491d03b41e 100644 --- a/opencga-storage/opencga-storage-core/src/test/java/org/opencb/opencga/storage/core/variant/annotation/DummyTestAnnotator.java +++ b/opencga-storage/opencga-storage-core/src/test/java/org/opencb/opencga/storage/core/variant/annotation/DummyTestAnnotator.java @@ -4,7 +4,9 @@ import org.opencb.biodata.models.variant.avro.AdditionalAttribute; import org.opencb.biodata.models.variant.avro.ConsequenceType; import org.opencb.biodata.models.variant.avro.VariantAnnotation; +import org.opencb.biodata.models.variant.avro.Xref; import org.opencb.commons.datastore.core.ObjectMap; +import org.opencb.commons.utils.CryptoUtils; import org.opencb.opencga.core.config.storage.StorageConfiguration; import org.opencb.opencga.storage.core.metadata.models.ProjectMetadata; import org.opencb.opencga.storage.core.variant.annotation.annotators.VariantAnnotator; @@ -29,6 +31,10 @@ public DummyTestAnnotator(StorageConfiguration configuration, ProjectMetadata pr fail = options.getBoolean(FAIL, false); } + static String getRs(Variant variant) { + return "rs" + variant.toString().hashCode(); + } + @Override public List annotate(List variants) throws VariantAnnotatorException { if (fail) { @@ -48,6 +54,7 @@ public List annotate(List variants) throws VariantAn ct.setExonOverlap(Collections.emptyList()); ct.setTranscriptFlags(Collections.emptyList()); a.setConsequenceTypes(Collections.singletonList(ct)); + a.setXrefs(Collections.singletonList(new Xref(getRs(v), "dbSNP"))); a.setAdditionalAttributes( Collections.singletonMap(GROUP_NAME.key(), new AdditionalAttribute(Collections.singletonMap(VARIANT_ID.key(), v.toString())))); diff --git a/opencga-storage/opencga-storage-core/src/test/java/org/opencb/opencga/storage/core/variant/annotation/VariantAnnotationManagerTest.java b/opencga-storage/opencga-storage-core/src/test/java/org/opencb/opencga/storage/core/variant/annotation/VariantAnnotationManagerTest.java index dc2721882fa..00544a3d715 100644 --- a/opencga-storage/opencga-storage-core/src/test/java/org/opencb/opencga/storage/core/variant/annotation/VariantAnnotationManagerTest.java +++ b/opencga-storage/opencga-storage-core/src/test/java/org/opencb/opencga/storage/core/variant/annotation/VariantAnnotationManagerTest.java @@ -4,6 +4,7 @@ import org.apache.commons.lang.StringUtils; import org.junit.Assume; import org.junit.Test; +import org.opencb.biodata.models.variant.Variant; import org.opencb.biodata.models.variant.avro.VariantAnnotation; import org.opencb.commons.datastore.core.ObjectMap; import org.opencb.commons.datastore.core.Query; @@ -262,6 +263,10 @@ public void testQueries(VariantStorageEngine variantStorageEngine) throws Storag assertThat(annotation.getConsequenceTypes(), VariantMatchers.isEmpty()); } + for (Variant variant : variantStorageEngine) { + Variant thisVariant = variantStorageEngine.getVariant(DummyTestAnnotator.getRs(variant)); + assertThat(thisVariant, VariantMatchers.samePosition(variant)); + } // Get annotations from a deleted snapshot thrown.expectMessage("Variant Annotation snapshot \"v1\" not found!"); diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/HadoopVariantStorageEngine.java b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/HadoopVariantStorageEngine.java index 917b679cf1c..2f0f6143b6b 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/HadoopVariantStorageEngine.java +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/HadoopVariantStorageEngine.java @@ -26,7 +26,6 @@ import org.apache.hadoop.hbase.client.HBaseAdmin; import org.apache.hadoop.hbase.util.Bytes; import org.apache.hadoop.util.StopWatch; -import org.opencb.biodata.models.variant.Variant; import org.opencb.biodata.models.variant.avro.VariantType; import org.opencb.commons.datastore.core.DataResult; import org.opencb.commons.datastore.core.ObjectMap; @@ -55,6 +54,7 @@ import org.opencb.opencga.storage.core.variant.adaptors.VariantQueryException; import org.opencb.opencga.storage.core.variant.adaptors.VariantQueryParam; import org.opencb.opencga.storage.core.variant.adaptors.iterators.VariantDBIterator; +import org.opencb.opencga.storage.core.variant.adaptors.sample.VariantSampleDataManager; import org.opencb.opencga.storage.core.variant.annotation.VariantAnnotationManager; import org.opencb.opencga.storage.core.variant.annotation.annotators.VariantAnnotator; import org.opencb.opencga.storage.core.variant.io.VariantExporter; @@ -1164,8 +1164,8 @@ public VariantStorageMetadataManager getMetadataManager() throws StorageEngineEx } @Override - public DataResult getSampleData(String variant, String study, QueryOptions options) throws StorageEngineException { - return new HBaseVariantSampleDataManager(getDBAdaptor(), getCellBaseUtils()).getSampleData(variant, study, options); + protected VariantSampleDataManager getVariantSampleDataManager() throws StorageEngineException { + return new HBaseVariantSampleDataManager(getDBAdaptor()); } @Override diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/adaptors/sample/HBaseVariantSampleDataManager.java b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/adaptors/sample/HBaseVariantSampleDataManager.java index 588833cfb6e..a96c57e9a45 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/adaptors/sample/HBaseVariantSampleDataManager.java +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/adaptors/sample/HBaseVariantSampleDataManager.java @@ -15,7 +15,6 @@ import org.opencb.commons.datastore.core.DataResult; import org.opencb.commons.datastore.core.QueryOptions; import org.opencb.opencga.storage.core.metadata.VariantStorageMetadataManager; -import org.opencb.opencga.storage.core.utils.CellBaseUtils; import org.opencb.opencga.storage.core.variant.VariantStorageOptions; import org.opencb.opencga.storage.core.variant.adaptors.GenotypeClass; import org.opencb.opencga.storage.core.variant.adaptors.VariantField; @@ -26,8 +25,8 @@ import org.opencb.opencga.storage.hadoop.variant.GenomeHelper; import org.opencb.opencga.storage.hadoop.variant.adaptors.VariantHadoopDBAdaptor; import org.opencb.opencga.storage.hadoop.variant.adaptors.phoenix.PhoenixHelper; -import org.opencb.opencga.storage.hadoop.variant.adaptors.phoenix.VariantPhoenixSchema; import org.opencb.opencga.storage.hadoop.variant.adaptors.phoenix.VariantPhoenixKeyFactory; +import org.opencb.opencga.storage.hadoop.variant.adaptors.phoenix.VariantPhoenixSchema; import org.opencb.opencga.storage.hadoop.variant.converters.HBaseVariantConverterConfiguration; import org.opencb.opencga.storage.hadoop.variant.converters.VariantRow; import org.opencb.opencga.storage.hadoop.variant.converters.annotation.HBaseToVariantAnnotationConverter; @@ -45,31 +44,20 @@ public class HBaseVariantSampleDataManager extends VariantSampleDataManager { private final VariantHadoopDBAdaptor dbAdaptor; private final VariantStorageMetadataManager metadataManager; - private final CellBaseUtils cellBaseUtils; - - public HBaseVariantSampleDataManager(VariantHadoopDBAdaptor dbAdaptor, CellBaseUtils cellBaseUtils) { + public HBaseVariantSampleDataManager(VariantHadoopDBAdaptor dbAdaptor) { super(dbAdaptor); this.dbAdaptor = dbAdaptor; metadataManager = dbAdaptor.getMetadataManager(); - this.cellBaseUtils = cellBaseUtils; } @Override - protected DataResult getSampleData(String variantStr, String study, QueryOptions options, + protected DataResult getSampleData(Variant variant, String study, QueryOptions options, List includeSamples, Set genotypes, int sampleLimit) { StopWatch stopWatch = StopWatch.createStarted(); Set includeFields = VariantField.getIncludeFields(options); - final Variant variant; - if (VariantQueryUtils.isVariantId(variantStr)) { - variant = new Variant(variantStr); - } else { - variant = cellBaseUtils.getVariant(variantStr); - } - variant.setId(variant.toString()); - int studyId = metadataManager.getStudyId(study); boolean includeNoneSamples = VariantQueryUtils.isNoneOrEmpty(includeSamples); @@ -172,7 +160,7 @@ protected DataResult getSampleData(String variantStr, String study, Que Result result = table.get(get); if (result == null || result.isEmpty()) { - throw VariantQueryException.variantNotFound(variantStr); + throw VariantQueryException.variantNotFound(variant.toString()); } // Walk row VariantRow.walker(result) From 86f68e660014cda5f0c324462a0dfd37c3bd0040 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacobo=20Coll=20Morag=C3=B3n?= Date: Fri, 12 Apr 2024 15:05:42 +0100 Subject: [PATCH 24/85] storage: Fix VariantQueryParam type. #TASK-5878 --- .../storage/core/variant/adaptors/VariantQueryParam.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/adaptors/VariantQueryParam.java b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/adaptors/VariantQueryParam.java index c10fd5def09..c801f4448ff 100644 --- a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/adaptors/VariantQueryParam.java +++ b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/adaptors/VariantQueryParam.java @@ -121,7 +121,7 @@ public final class VariantQueryParam implements QueryParam { public static final String INCLUDE_SAMPLE_ID_DESCR = "Include sampleId on each result"; - public static final VariantQueryParam INCLUDE_SAMPLE_ID = new VariantQueryParam("includeSampleId", TEXT_ARRAY, INCLUDE_SAMPLE_ID_DESCR); + public static final VariantQueryParam INCLUDE_SAMPLE_ID = new VariantQueryParam("includeSampleId", BOOLEAN, INCLUDE_SAMPLE_ID_DESCR); public static final String SAMPLE_METADATA_DESCR = "Return the samples metadata group by study. Sample names will appear in the same order as their corresponding genotypes."; From 8a9dcc51bf652d135687c986bbf99c4c394a573d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacobo=20Coll=20Morag=C3=B3n?= Date: Tue, 16 Apr 2024 14:37:55 +0100 Subject: [PATCH 25/85] storage: Require ParsedVariantQuery for creating VariantQueryResults. #TASK-5876 --- .../ClinicalInterpretationManager.java | 2 +- .../ExomiserInterpretationAnalysis.java | 2 +- ...TieringInterpretationAnalysisExecutor.java | 2 +- .../ZettaInterpretationAnalysisExecutor.java | 3 +- .../manager/VariantStorageManager.java | 16 +-- ...ationalSignatureLocalAnalysisExecutor.java | 2 +- .../app/cli/main/io/VcfOutputWriter.java | 2 +- .../core/variant/VariantStorageEngine.java | 28 ++-- .../variant/adaptors/VariantDBAdaptor.java | 36 ++--- .../core/variant/adaptors/VariantQuery.java | 4 + .../iterators/LimitVariantDBIterator.java | 18 ++- .../adaptors/iterators/VariantDBIterator.java | 33 +++-- .../variant/query/ParsedVariantQuery.java | 126 +++++++++++++++++- .../variant/query/VariantQueryParser.java | 24 +++- .../variant/query}/VariantQueryResult.java | 110 ++++++++++----- .../core/variant/query/VariantQueryUtils.java | 38 +----- ...AbstractTwoPhasedVariantQueryExecutor.java | 2 +- .../BreakendVariantQueryExecutor.java | 83 +++++------- ...hromDensityVariantAggregationExecutor.java | 4 +- .../CompoundHeterozygousQueryExecutor.java | 49 ++++--- .../DBAdaptorVariantQueryExecutor.java | 15 +-- .../executors/NoOpVariantQueryExecutor.java | 9 +- .../executors/VariantAggregationExecutor.java | 2 +- .../query/executors/VariantQueryExecutor.java | 33 ++--- .../query/filters/VariantFilterBuilder.java | 81 +++++------ .../projection/VariantQueryProjection.java | 14 ++ .../VariantQueryProjectionParser.java | 12 +- ...amplesSearchIndexVariantQueryExecutor.java | 23 +--- ...SearchIndexVariantAggregationExecutor.java | 2 +- .../SearchIndexVariantQueryExecutor.java | 40 +++--- .../search/solr/VariantSearchManager.java | 18 +-- .../variant/VariantStorageEngineBNDTest.java | 30 +++-- .../VariantStorageSearchIntersectTest.java | 10 +- ...ultiFileSpecificSamplesCollectionTest.java | 11 +- .../VariantDBAdaptorMultiFileTest.java | 2 +- .../adaptors/VariantDBAdaptorTest.java | 12 +- .../VariantQueryUsingSearchIndexTest.java | 2 +- .../variant/dummy/DummyVariantDBAdaptor.java | 13 +- .../variant/query/VariantQueryParserTest.java | 17 ++- .../search/SearchIndexSamplesTest.java | 3 +- .../search/VariantSearchIndexTest.java | 2 +- .../variant/search/VariantSearchTest.java | 10 +- .../variant/HadoopVariantQueryParser.java | 36 +++++ .../variant/HadoopVariantStorageEngine.java | 67 +++++----- ...seColumnIntersectVariantQueryExecutor.java | 16 +-- .../adaptors/VariantHadoopDBAdaptor.java | 38 +++--- .../phoenix/VariantSqlQueryParser.java | 3 +- ...ndexCompoundHeterozygousQueryExecutor.java | 2 +- ...ampleIndexMendelianErrorQueryExecutor.java | 5 +- .../SampleIndexOnlyVariantQueryExecutor.java | 38 ++---- ...SampleIndexVariantAggregationExecutor.java | 4 +- .../SampleIndexVariantQueryExecutor.java | 38 +++--- .../variant/index/query/SampleIndexQuery.java | 11 +- .../index/query/SingleSampleIndexQuery.java | 3 +- .../index/sample/SampleIndexQueryParser.java | 2 +- .../variant/io/VariantExporterDriver.java | 3 +- .../variant/mr/VariantMapReduceUtil.java | 6 +- .../HadoopVariantStorageEngineSVTest.java | 3 +- .../HadoopVariantDBAdaptorMultiFileTest.java | 3 +- .../HadoopVariantDBAdaptorNativeTest.java | 2 +- .../hadoop/variant/gaps/FillGapsTest.java | 2 +- .../variant/index/family/FamilyIndexTest.java | 2 +- .../sample/SampleIndexDBAdaptorTest.java | 2 +- .../SampleIndexDuplicatedVariantsTest.java | 8 +- .../sample/SampleIndexEntryFilterTest.java | 2 +- .../sample/SampleIndexQueryParserTest.java | 4 +- .../variant/index/sample/SampleIndexTest.java | 32 ++--- .../server/rest/VariantRestWebService.java | 2 +- 68 files changed, 717 insertions(+), 562 deletions(-) rename {opencga-core/src/main/java/org/opencb/opencga/core/response => opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query}/VariantQueryResult.java (61%) create mode 100644 opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/HadoopVariantQueryParser.java diff --git a/opencga-analysis/src/main/java/org/opencb/opencga/analysis/clinical/ClinicalInterpretationManager.java b/opencga-analysis/src/main/java/org/opencb/opencga/analysis/clinical/ClinicalInterpretationManager.java index 3ca18fe0eb9..f240d877fc5 100644 --- a/opencga-analysis/src/main/java/org/opencb/opencga/analysis/clinical/ClinicalInterpretationManager.java +++ b/opencga-analysis/src/main/java/org/opencb/opencga/analysis/clinical/ClinicalInterpretationManager.java @@ -61,7 +61,7 @@ import org.opencb.opencga.core.models.study.Study; import org.opencb.opencga.core.models.user.User; import org.opencb.opencga.core.response.OpenCGAResult; -import org.opencb.opencga.core.response.VariantQueryResult; +import org.opencb.opencga.storage.core.variant.query.VariantQueryResult; import org.opencb.opencga.storage.core.StorageEngineFactory; import org.opencb.opencga.storage.core.clinical.ClinicalVariantEngine; import org.opencb.opencga.storage.core.clinical.ClinicalVariantException; diff --git a/opencga-analysis/src/main/java/org/opencb/opencga/analysis/clinical/exomiser/ExomiserInterpretationAnalysis.java b/opencga-analysis/src/main/java/org/opencb/opencga/analysis/clinical/exomiser/ExomiserInterpretationAnalysis.java index 39fa4fd581c..fc82cdc73fd 100644 --- a/opencga-analysis/src/main/java/org/opencb/opencga/analysis/clinical/exomiser/ExomiserInterpretationAnalysis.java +++ b/opencga-analysis/src/main/java/org/opencb/opencga/analysis/clinical/exomiser/ExomiserInterpretationAnalysis.java @@ -44,7 +44,7 @@ import org.opencb.opencga.core.models.common.Enums; import org.opencb.opencga.core.models.individual.Individual; import org.opencb.opencga.core.response.OpenCGAResult; -import org.opencb.opencga.core.response.VariantQueryResult; +import org.opencb.opencga.storage.core.variant.query.VariantQueryResult; import org.opencb.opencga.core.tools.annotations.Tool; import org.opencb.opencga.storage.core.exceptions.StorageEngineException; import org.opencb.opencga.storage.core.variant.adaptors.VariantQueryParam; diff --git a/opencga-analysis/src/main/java/org/opencb/opencga/analysis/clinical/tiering/CancerTieringInterpretationAnalysisExecutor.java b/opencga-analysis/src/main/java/org/opencb/opencga/analysis/clinical/tiering/CancerTieringInterpretationAnalysisExecutor.java index ce89757143a..ea8dc7c3c89 100644 --- a/opencga-analysis/src/main/java/org/opencb/opencga/analysis/clinical/tiering/CancerTieringInterpretationAnalysisExecutor.java +++ b/opencga-analysis/src/main/java/org/opencb/opencga/analysis/clinical/tiering/CancerTieringInterpretationAnalysisExecutor.java @@ -41,7 +41,7 @@ import org.opencb.opencga.core.models.individual.Individual; import org.opencb.opencga.core.models.sample.Sample; import org.opencb.opencga.core.response.OpenCGAResult; -import org.opencb.opencga.core.response.VariantQueryResult; +import org.opencb.opencga.storage.core.variant.query.VariantQueryResult; import org.opencb.opencga.core.tools.OpenCgaToolExecutor; import org.opencb.opencga.core.tools.annotations.ToolExecutor; import org.opencb.opencga.storage.core.exceptions.StorageEngineException; diff --git a/opencga-analysis/src/main/java/org/opencb/opencga/analysis/clinical/zetta/ZettaInterpretationAnalysisExecutor.java b/opencga-analysis/src/main/java/org/opencb/opencga/analysis/clinical/zetta/ZettaInterpretationAnalysisExecutor.java index c45f0b484a9..cbf7e8211d2 100644 --- a/opencga-analysis/src/main/java/org/opencb/opencga/analysis/clinical/zetta/ZettaInterpretationAnalysisExecutor.java +++ b/opencga-analysis/src/main/java/org/opencb/opencga/analysis/clinical/zetta/ZettaInterpretationAnalysisExecutor.java @@ -28,7 +28,7 @@ import org.opencb.opencga.analysis.clinical.ClinicalUtils; import org.opencb.opencga.catalog.exceptions.CatalogException; import org.opencb.opencga.core.exceptions.ToolException; -import org.opencb.opencga.core.response.VariantQueryResult; +import org.opencb.opencga.storage.core.variant.query.VariantQueryResult; import org.opencb.opencga.core.tools.OpenCgaToolExecutor; import org.opencb.opencga.core.tools.annotations.ToolExecutor; import org.opencb.opencga.storage.core.exceptions.StorageEngineException; @@ -40,7 +40,6 @@ import java.util.Map; import static org.opencb.opencga.analysis.clinical.InterpretationAnalysis.PRIMARY_FINDINGS_FILENAME; -import static org.opencb.opencga.analysis.clinical.InterpretationAnalysis.SECONDARY_FINDINGS_FILENAME; import static org.opencb.opencga.analysis.variant.manager.VariantCatalogQueryUtils.FAMILY_SEGREGATION; @ToolExecutor(id = "opencga-local", diff --git a/opencga-analysis/src/main/java/org/opencb/opencga/analysis/variant/manager/VariantStorageManager.java b/opencga-analysis/src/main/java/org/opencb/opencga/analysis/variant/manager/VariantStorageManager.java index bf0db6f34eb..344160872bf 100644 --- a/opencga-analysis/src/main/java/org/opencb/opencga/analysis/variant/manager/VariantStorageManager.java +++ b/opencga-analysis/src/main/java/org/opencb/opencga/analysis/variant/manager/VariantStorageManager.java @@ -70,7 +70,7 @@ import org.opencb.opencga.core.models.study.StudyPermissions; import org.opencb.opencga.core.models.variant.VariantPruneParams; import org.opencb.opencga.core.response.OpenCGAResult; -import org.opencb.opencga.core.response.VariantQueryResult; +import org.opencb.opencga.storage.core.variant.query.VariantQueryResult; import org.opencb.opencga.core.tools.ToolParams; import org.opencb.opencga.storage.core.StorageEngineFactory; import org.opencb.opencga.storage.core.StoragePipelineResult; @@ -630,6 +630,7 @@ public VariantQueryResult get(Query inputQuery, QueryOptions queryOptio @SuppressWarnings("unchecked") public VariantQueryResult get(Query query, QueryOptions queryOptions, String token, Class clazz) throws CatalogException, IOException, StorageEngineException { + VariantQueryResult result = get(query, queryOptions, token); List variants; if (clazz == Variant.class) { @@ -643,16 +644,7 @@ public VariantQueryResult get(Query query, QueryOptions queryOptions, Str } else { throw new IllegalArgumentException("Unknown variant format " + clazz); } - return new VariantQueryResult<>( - result.getTime(), - result.getNumResults(), - result.getNumMatches(), - result.getEvents(), - variants, - result.getSamples(), - result.getSource(), - result.getApproximateCount(), - result.getApproximateCountSamplingSize(), null); + return new VariantQueryResult<>(result, variants); } @@ -883,7 +875,7 @@ public DataResult getSampleData(String variant, String study, QueryOpti VariantQueryResult result = new VariantQueryResult<>( ((int) stopWatch.getTime(TimeUnit.MILLISECONDS)), - 1, 1, new ArrayList<>(), Collections.singletonList(variantResult), null, null) + 1, 1, new ArrayList<>(), Collections.singletonList(variantResult), engine.getStorageEngineId()) .setNumSamples(sampleEntries.size()); if (exactNumSamples) { result.setApproximateCount(false); diff --git a/opencga-analysis/src/main/java/org/opencb/opencga/analysis/variant/mutationalSignature/MutationalSignatureLocalAnalysisExecutor.java b/opencga-analysis/src/main/java/org/opencb/opencga/analysis/variant/mutationalSignature/MutationalSignatureLocalAnalysisExecutor.java index 042784b844a..5be8325e066 100644 --- a/opencga-analysis/src/main/java/org/opencb/opencga/analysis/variant/mutationalSignature/MutationalSignatureLocalAnalysisExecutor.java +++ b/opencga-analysis/src/main/java/org/opencb/opencga/analysis/variant/mutationalSignature/MutationalSignatureLocalAnalysisExecutor.java @@ -43,7 +43,7 @@ import org.opencb.opencga.core.models.sample.Sample; import org.opencb.opencga.core.models.variant.MutationalSignatureAnalysisParams; import org.opencb.opencga.core.response.OpenCGAResult; -import org.opencb.opencga.core.response.VariantQueryResult; +import org.opencb.opencga.storage.core.variant.query.VariantQueryResult; import org.opencb.opencga.core.tools.annotations.ToolExecutor; import org.opencb.opencga.core.tools.variant.MutationalSignatureAnalysisExecutor; import org.opencb.opencga.storage.core.exceptions.StorageEngineException; diff --git a/opencga-app/src/main/java/org/opencb/opencga/app/cli/main/io/VcfOutputWriter.java b/opencga-app/src/main/java/org/opencb/opencga/app/cli/main/io/VcfOutputWriter.java index 6093c975a32..0c398dd2ef6 100644 --- a/opencga-app/src/main/java/org/opencb/opencga/app/cli/main/io/VcfOutputWriter.java +++ b/opencga-app/src/main/java/org/opencb/opencga/app/cli/main/io/VcfOutputWriter.java @@ -9,7 +9,7 @@ import org.opencb.biodata.models.variant.metadata.VariantStudyMetadata; import org.opencb.biodata.models.variant.protobuf.VariantProto; import org.opencb.opencga.core.response.RestResponse; -import org.opencb.opencga.core.response.VariantQueryResult; +import org.opencb.opencga.storage.core.variant.query.VariantQueryResult; import org.opencb.opencga.storage.core.variant.io.VcfDataWriter; import java.io.PrintStream; diff --git a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/VariantStorageEngine.java b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/VariantStorageEngine.java index a3ab7e539b5..c518313d773 100644 --- a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/VariantStorageEngine.java +++ b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/VariantStorageEngine.java @@ -31,7 +31,7 @@ import org.opencb.opencga.core.config.storage.StorageConfiguration; import org.opencb.opencga.core.models.operations.variant.VariantAggregateFamilyParams; import org.opencb.opencga.core.models.operations.variant.VariantAggregateParams; -import org.opencb.opencga.core.response.VariantQueryResult; +import org.opencb.opencga.storage.core.variant.query.VariantQueryResult; import org.opencb.opencga.storage.core.StorageEngine; import org.opencb.opencga.storage.core.StoragePipelineResult; import org.opencb.opencga.storage.core.exceptions.StorageEngineException; @@ -1205,8 +1205,8 @@ public VariantQueryResult get(Query query, QueryOptions options) { } addDefaultLimit(options, getOptions()); addDefaultSampleLimit(query, getOptions()); - query = preProcessQuery(query, options); - return getVariantQueryExecutor(query, options).get(query, options); + ParsedVariantQuery variantQuery = parseQuery(query, options); + return getVariantQueryExecutor(variantQuery).get(variantQuery); } @Override @@ -1223,8 +1223,8 @@ public MultiVariantDBIterator iterator(Iterator variants, Query query, QueryO public VariantDBIterator iterator(Query query, QueryOptions options) { query = VariantQueryUtils.copy(query); options = VariantQueryUtils.copy(options); - query = preProcessQuery(query, options); - return getVariantQueryExecutor(query, options).iterator(query, options); + ParsedVariantQuery variantQuery = parseQuery(query, options); + return getVariantQueryExecutor(variantQuery).iterator(variantQuery); } public final List getVariantQueryExecutors() throws StorageEngineException { @@ -1246,7 +1246,7 @@ protected List initVariantQueryExecutors() throws StorageE executors.add(new CompoundHeterozygousQueryExecutor( getMetadataManager(), getStorageEngineId(), getOptions(), this)); executors.add(new BreakendVariantQueryExecutor( - getMetadataManager(), getStorageEngineId(), getOptions(), new DBAdaptorVariantQueryExecutor( + getStorageEngineId(), getOptions(), new DBAdaptorVariantQueryExecutor( getDBAdaptor(), getStorageEngineId(), getOptions()), getDBAdaptor())); executors.add(new SamplesSearchIndexVariantQueryExecutor( getDBAdaptor(), getVariantSearchManager(), getStorageEngineId(), dbName, configuration, getOptions())); @@ -1265,12 +1265,22 @@ protected List initVariantQueryExecutors() throws StorageE * @return VariantQueryExecutor to use */ public VariantQueryExecutor getVariantQueryExecutor(Query query, QueryOptions options) { + return getVariantQueryExecutor(parseQuery(query, options)); + } + + /** + * Determine which {@link VariantQueryExecutor} should be used to execute the given query. + * + * @param variantQuery Parsed variant query + * @return VariantQueryExecutor to use + */ + public VariantQueryExecutor getVariantQueryExecutor(ParsedVariantQuery variantQuery) { try { for (VariantQueryExecutor executor : getVariantQueryExecutors()) { - if (executor.canUseThisExecutor(query, options)) { + if (executor.canUseThisExecutor(variantQuery.getQuery(), variantQuery.getInputOptions())) { logger.info("Using VariantQueryExecutor : " + executor.getClass().getName()); - logger.info(" Query : " + VariantQueryUtils.printQuery(query)); - logger.info(" Options : " + options.toJson()); + logger.info(" Query : " + VariantQueryUtils.printQuery(variantQuery.getInputQuery())); + logger.info(" Options : " + variantQuery.getInputOptions().toJson()); return executor; } } diff --git a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/adaptors/VariantDBAdaptor.java b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/adaptors/VariantDBAdaptor.java index c2ee42c9b00..e54efca912a 100644 --- a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/adaptors/VariantDBAdaptor.java +++ b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/adaptors/VariantDBAdaptor.java @@ -23,12 +23,12 @@ import org.opencb.commons.datastore.core.DataResult; import org.opencb.commons.datastore.core.Query; import org.opencb.commons.datastore.core.QueryOptions; -import org.opencb.opencga.core.response.VariantQueryResult; import org.opencb.opencga.storage.core.metadata.VariantStorageMetadataManager; import org.opencb.opencga.storage.core.metadata.models.StudyMetadata; import org.opencb.opencga.storage.core.variant.adaptors.iterators.VariantDBIterator; import org.opencb.opencga.storage.core.variant.query.ParsedVariantQuery; import org.opencb.opencga.storage.core.variant.query.VariantQueryParser; +import org.opencb.opencga.storage.core.variant.query.VariantQueryResult; import org.opencb.opencga.storage.core.variant.query.projection.VariantQueryProjectionParser; import org.opencb.opencga.storage.core.variant.stats.VariantStatsWrapper; @@ -37,8 +37,6 @@ import java.util.List; import java.util.Map; -import static org.opencb.opencga.storage.core.variant.query.VariantQueryUtils.addSamplesMetadataIfRequested; - /** * @author Ignacio Medina * @author Jacobo Coll @@ -46,21 +44,6 @@ */ public interface VariantDBAdaptor extends VariantIterable, AutoCloseable { - /** - * This method inserts Variants into the given Study. If the Study already exists then it just adds the new Sample - * genotypes, also new variants are inserted. If it is a new Study then Sample genotypes are added to the new Study. - * - * @param variants List of variants in OpenCB data model to be inserted - * @param studyName Name or alias of the study - * @param options Query modifiers, accepted values are: include, exclude, limit, skip, sort and count - * @return A DataResult with the number of inserted variants - */ - @Deprecated - default DataResult insert(List variants, String studyName, QueryOptions options) { - throw new UnsupportedOperationException(); - } - - /** /** * Fetch all variants resulting of executing the query in the database. Returned fields are taken from * the 'include' and 'exclude' fields at options. @@ -71,26 +54,29 @@ default DataResult insert(List variants, String studyName, QueryOptions * @return A DataResult with the result of the query */ default VariantQueryResult get(Iterator variants, Query query, QueryOptions options) { - DataResult queryResult = iterator(variants, query, options).toDataResult(); - return addSamplesMetadataIfRequested(queryResult, query, options, getMetadataManager()); + ParsedVariantQuery variantQuery = new VariantQueryParser(null, getMetadataManager()).parseQuery(query, options, true); + try (VariantDBIterator iterator = iterator(variants, query, options)) { + return iterator.toDataResult(variantQuery); + } catch (Exception e) { + throw VariantQueryException.internalException(e); + } } @Deprecated default VariantDBIterator iterator(Query query, QueryOptions options) { - return iterator(new VariantQueryParser(null, getMetadataManager()).parseQuery(query, options, true), options); + return iterator(new VariantQueryParser(null, getMetadataManager()).parseQuery(query, options, true)); } - VariantDBIterator iterator(ParsedVariantQuery query, QueryOptions options); + VariantDBIterator iterator(ParsedVariantQuery query); /** * Fetch all variants resulting of executing the query in the database. Returned fields are taken from * the 'include' and 'exclude' fields at options. * * @param query Query to be executed in the database to filter variants - * @param options Query modifiers, accepted values are: include, exclude, limit, skip, sort and count * @return A DataResult with the result of the query */ - VariantQueryResult get(ParsedVariantQuery query, QueryOptions options); + VariantQueryResult get(ParsedVariantQuery query); /** * Fetch all variants resulting of executing the query in the database. Returned fields are taken from @@ -102,7 +88,7 @@ default VariantDBIterator iterator(Query query, QueryOptions options) { */ @Deprecated default VariantQueryResult get(Query query, QueryOptions options) { - return get(new VariantQueryParser(null, getMetadataManager()).parseQuery(query, options, true), options); + return get(new VariantQueryParser(null, getMetadataManager()).parseQuery(query, options, true)); } /** diff --git a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/adaptors/VariantQuery.java b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/adaptors/VariantQuery.java index 65c2bda05e6..59f439897a5 100644 --- a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/adaptors/VariantQuery.java +++ b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/adaptors/VariantQuery.java @@ -50,6 +50,10 @@ public VariantQuery region(String value) { put(VariantQueryParam.REGION.key(), value); return this; } + public VariantQuery region(String... value) { + put(VariantQueryParam.REGION.key(), Arrays.asList(value)); + return this; + } public VariantQuery region(Region... value) { put(VariantQueryParam.REGION.key(), Arrays.asList(value)); return this; diff --git a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/adaptors/iterators/LimitVariantDBIterator.java b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/adaptors/iterators/LimitVariantDBIterator.java index 3f69fe91924..07ece2a578d 100644 --- a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/adaptors/iterators/LimitVariantDBIterator.java +++ b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/adaptors/iterators/LimitVariantDBIterator.java @@ -1,16 +1,32 @@ package org.opencb.opencga.storage.core.variant.adaptors.iterators; +import org.opencb.biodata.models.variant.Variant; + +import java.util.NoSuchElementException; + public class LimitVariantDBIterator extends DelegatedVariantDBIterator { private final int limit; + private int count; LimitVariantDBIterator(VariantDBIterator delegated, int limit) { super(delegated); this.limit = limit; + this.count = 0; } @Override public boolean hasNext() { - return getCount() < limit && super.hasNext(); + return count < limit && super.hasNext(); + } + + @Override + public Variant next() { + if (!this.hasNext()) { + throw new NoSuchElementException(); + } else { + ++this.count; + return super.next(); + } } } diff --git a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/adaptors/iterators/VariantDBIterator.java b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/adaptors/iterators/VariantDBIterator.java index eae841fc766..f070c4c7bb1 100644 --- a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/adaptors/iterators/VariantDBIterator.java +++ b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/adaptors/iterators/VariantDBIterator.java @@ -16,14 +16,14 @@ package org.opencb.opencga.storage.core.variant.adaptors.iterators; -import com.google.common.collect.Iterators; import org.opencb.biodata.models.variant.Variant; import org.opencb.biodata.models.variant.avro.VariantAvro; import org.opencb.commons.datastore.core.DataResult; import org.opencb.commons.datastore.core.QueryOptions; -import org.opencb.opencga.core.response.VariantQueryResult; import org.opencb.opencga.storage.core.utils.iterators.CloseableIterator; import org.opencb.opencga.storage.core.variant.adaptors.VariantQueryException; +import org.opencb.opencga.storage.core.variant.query.ParsedVariantQuery; +import org.opencb.opencga.storage.core.variant.query.VariantQueryResult; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -131,21 +131,34 @@ public final void forEachRemaining(Consumer action) { } } - public final DataResult toDataResult() { + + // TODO: The VariantDBIterator should be able to return the samples in the result + // This class should contain a ParsedVariantQuery +// public final VariantQueryResult toVariantQueryResult() { +// } + + public final VariantQueryResult toDataResult(ParsedVariantQuery variantQuery) { List result = new ArrayList<>(); this.forEachRemaining(result::add); int numResults = result.size(); int numTotalResults = -1; // Unknown numTotalResults - return new DataResult<>((int) getTimeFetching(TimeUnit.MILLISECONDS), Collections.emptyList(), numResults, result, numTotalResults); + DataResult dataResult = new DataResult<>((int) + getTimeFetching(TimeUnit.MILLISECONDS), + Collections.emptyList(), + numResults, + result, + numTotalResults); + return new VariantQueryResult<>(dataResult, variantQuery); } - public final VariantQueryResult toDataResult(Map> samples) { - return new VariantQueryResult<>(toDataResult(), samples); + public final List toList() { + List result = new ArrayList<>(); + this.forEachRemaining(result::add); + return result; } - protected interface TimeFunction { R call() throws E; } @@ -192,7 +205,11 @@ public VariantDBIterator filter(Predicate filter) { } public VariantDBIterator localSkip(int skip) { - Iterators.advance(this, skip); + int i = 0; + while (i < skip && hasNext()) { + next(); + i++; + } return this; } diff --git a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/ParsedVariantQuery.java b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/ParsedVariantQuery.java index 9c89ffb5b61..586985a8d45 100644 --- a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/ParsedVariantQuery.java +++ b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/ParsedVariantQuery.java @@ -1,17 +1,20 @@ package org.opencb.opencga.storage.core.variant.query; +import org.opencb.biodata.models.core.Region; import org.opencb.biodata.models.variant.Variant; import org.opencb.commons.datastore.core.Query; import org.opencb.commons.datastore.core.QueryOptions; import org.opencb.opencga.storage.core.metadata.models.SampleMetadata; import org.opencb.opencga.storage.core.metadata.models.StudyMetadata; import org.opencb.opencga.storage.core.metadata.models.StudyResourceMetadata; +import org.opencb.opencga.storage.core.variant.adaptors.VariantQueryException; import org.opencb.opencga.storage.core.variant.adaptors.VariantQueryParam; import org.opencb.opencga.storage.core.variant.query.projection.VariantQueryProjection; import java.util.*; import java.util.stream.Collectors; +import static org.opencb.opencga.storage.core.variant.adaptors.VariantQueryParam.*; import static org.opencb.opencga.storage.core.variant.query.VariantQueryUtils.ID_INTERSECT; public class ParsedVariantQuery { @@ -24,7 +27,15 @@ public class ParsedVariantQuery { private VariantQueryProjection projection; private final VariantStudyQuery studyQuery; -// private VariantAnnotationQuery annotationQuery; + private Integer limit; + private int skip; + private boolean count; + private int approximateCountSamplingSize; + private List geneRegions; + private List regions; + private List> clinicalCombination; + private List clinicalCombinationList; + // private VariantAnnotationQuery annotationQuery; public ParsedVariantQuery() { @@ -46,8 +57,16 @@ public ParsedVariantQuery(ParsedVariantQuery other) { this.inputOptions = new QueryOptions(other.inputOptions); this.query = new Query(other.query); this.projection = other.projection; - this.studyQuery = other.studyQuery; + this.studyQuery = new VariantStudyQuery(other.getStudyQuery()); this.optimized = other.optimized; + this.limit = other.limit; + this.skip = other.skip; + this.count = other.count; + this.approximateCountSamplingSize = other.approximateCountSamplingSize; + this.geneRegions = new ArrayList<>(other.geneRegions); + this.regions = new ArrayList<>(other.regions); + this.clinicalCombination = new ArrayList<>(other.clinicalCombination); + this.clinicalCombinationList = new ArrayList<>(other.clinicalCombinationList); } public Query getInputQuery() { @@ -107,6 +126,24 @@ public VariantQueryXref getXrefs() { return VariantQueryParser.parseXrefs(query); } + public List getRegions() { + return regions; + } + + public ParsedVariantQuery setRegions(List regions) { + this.regions = regions; + return this; + } + + public List getGeneRegions() { + return geneRegions; + } + + public ParsedVariantQuery setGeneRegions(List geneRegions) { + this.geneRegions = geneRegions; + return this; + } + public List getConsequenceTypes() { return VariantQueryUtils.parseConsequenceTypes(query.getAsStringList(VariantQueryParam.ANNOT_CONSEQUENCE_TYPE.key())); } @@ -119,6 +156,76 @@ public List getTranscriptFlags() { return query.getAsStringList(VariantQueryParam.ANNOT_TRANSCRIPT_FLAG.key()); } + public Integer getLimit() { + return limit; + } + + public int getLimitOr(int defaultValue) { + return limit == null ? defaultValue : limit; + } + + public ParsedVariantQuery setLimit(Integer limit) { + this.limit = limit; + return this; + } + + public int getSkip() { + return skip; + } + + public ParsedVariantQuery setSkip(int skip) { + this.skip = skip; + return this; + } + + public boolean getCount() { + return count; + } + + public ParsedVariantQuery setCount(boolean count) { + this.count = count; + return this; + } + + public int getApproximateCountSamplingSize() { + return approximateCountSamplingSize; + } + + public ParsedVariantQuery setApproximateCountSamplingSize(int approximateCountSamplingSize) { + this.approximateCountSamplingSize = approximateCountSamplingSize; + return this; + } + + public ParsedQuery> getPopulationFrequencyAlt() { + return VariantQueryParser.parseFreqFilter(query, ANNOT_POPULATION_ALTERNATE_FREQUENCY); + } + + public ParsedQuery> getPopulationFrequencyRef() { + return VariantQueryParser.parseFreqFilter(query, ANNOT_POPULATION_REFERENCE_FREQUENCY); + } + + public ParsedQuery> getPopulationFrequencyMaf() { + return VariantQueryParser.parseFreqFilter(query, ANNOT_POPULATION_MINOR_ALLELE_FREQUENCY); + } + + public List> getClinicalCombinations() { + return clinicalCombination; + } + + public ParsedVariantQuery setClinicalCombination(List> clinicalCombination) { + this.clinicalCombination = clinicalCombination; + return this; + } + + public List getClinicalCombinationsList() { + return clinicalCombinationList; + } + + public ParsedVariantQuery setClinicalCombinationList(List clinicalCombinationList) { + this.clinicalCombinationList = clinicalCombinationList; + return this; + } + public static class VariantStudyQuery { private ParsedQuery studies; private ParsedQuery>> genotypes; @@ -131,6 +238,13 @@ public static class VariantStudyQuery { public VariantStudyQuery() { } + public VariantStudyQuery(VariantStudyQuery studyQuery) { + this.studies = studyQuery.studies; + this.genotypes = studyQuery.genotypes; + this.sampleDataQuery = studyQuery.sampleDataQuery; + this.defaultStudy = studyQuery.defaultStudy; + } + public ParsedQuery getStudies() { return studies; } @@ -140,6 +254,14 @@ public VariantStudyQuery setStudies(ParsedQuery studies) { return this; } + public String getStudyOrFail() { + if (studies == null || studies.size() != 1) { + throw new VariantQueryException("Require exactly one study"); + } else { + return studies.get(0); + } + } + public ParsedQuery>> getGenotypes() { return genotypes; } diff --git a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/VariantQueryParser.java b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/VariantQueryParser.java index 1564ad0fabf..aa07aaf3687 100644 --- a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/VariantQueryParser.java +++ b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/VariantQueryParser.java @@ -19,6 +19,7 @@ import org.opencb.opencga.storage.core.metadata.models.TaskMetadata; import org.opencb.opencga.storage.core.metadata.models.VariantScoreMetadata; import org.opencb.opencga.storage.core.utils.CellBaseUtils; +import org.opencb.opencga.storage.core.variant.VariantStorageOptions; import org.opencb.opencga.storage.core.variant.adaptors.GenotypeClass; import org.opencb.opencga.storage.core.variant.adaptors.VariantQueryException; import org.opencb.opencga.storage.core.variant.adaptors.VariantQueryParam; @@ -157,6 +158,13 @@ public ParsedVariantQuery parseQuery(Query query, QueryOptions options, boolean } ParsedVariantQuery variantQuery = new ParsedVariantQuery(new Query(query), new QueryOptions(options)); + int limit = options.getInt(QueryOptions.LIMIT, -1); + variantQuery.setLimit(limit == -1 ? null : limit); + variantQuery.setSkip(options.getInt(QueryOptions.SKIP, 0)); + variantQuery.setCount(options.getBoolean(QueryOptions.COUNT, false)); + variantQuery.setApproximateCountSamplingSize(options.getInt( + VariantStorageOptions.APPROXIMATE_COUNT_SAMPLING_SIZE.key(), + VariantStorageOptions.APPROXIMATE_COUNT_SAMPLING_SIZE.defaultValue())); if (!skipPreProcess) { query = preProcessQuery(query, options); @@ -164,6 +172,13 @@ public ParsedVariantQuery parseQuery(Query query, QueryOptions options, boolean variantQuery.setQuery(query); variantQuery.setProjection(projectionParser.parseVariantQueryProjection(query, options)); + List geneRegions = Region.parseRegions(query.getString(ANNOT_GENE_REGIONS.key())); + variantQuery.setGeneRegions(geneRegions == null ? Collections.emptyList() : geneRegions); + List regions = Region.parseRegions(query.getString(REGION.key()), true); + variantQuery.setRegions(regions == null ? Collections.emptyList() : regions); + variantQuery.setClinicalCombination(VariantQueryParser.parseClinicalCombination(query, false)); + variantQuery.setClinicalCombinationList(VariantQueryParser.parseClinicalCombinationsList(query, false)); + ParsedVariantQuery.VariantStudyQuery studyQuery = variantQuery.getStudyQuery(); StudyMetadata defaultStudy = getDefaultStudy(query); @@ -685,13 +700,8 @@ protected void preProcessStudyParams(Query query, QueryOptions options) { } } if (!isValidParam(query, INCLUDE_SAMPLE) || selectVariantElements.getSamplePagination()) { - List includeSample = selectVariantElements.getSamples() - .entrySet() - .stream() - .flatMap(e -> e.getValue() - .stream() - .map(s -> metadataManager.getSampleName(e.getKey(), s))) - .collect(Collectors.toList()); + List includeSample = selectVariantElements.getSampleNames().values() + .stream().flatMap(Collection::stream).collect(Collectors.toList()); if (includeSample.isEmpty()) { query.put(INCLUDE_SAMPLE.key(), NONE); } else { diff --git a/opencga-core/src/main/java/org/opencb/opencga/core/response/VariantQueryResult.java b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/VariantQueryResult.java similarity index 61% rename from opencga-core/src/main/java/org/opencb/opencga/core/response/VariantQueryResult.java rename to opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/VariantQueryResult.java index c955b3ca379..79645987303 100644 --- a/opencga-core/src/main/java/org/opencb/opencga/core/response/VariantQueryResult.java +++ b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/VariantQueryResult.java @@ -14,16 +14,21 @@ * limitations under the License. */ -package org.opencb.opencga.core.response; +package org.opencb.opencga.storage.core.variant.query; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import org.opencb.commons.datastore.core.DataResult; import org.opencb.commons.datastore.core.Event; import org.opencb.commons.datastore.core.ObjectMap; +import org.opencb.opencga.core.response.OpenCGAResult; +import org.opencb.opencga.storage.core.variant.query.projection.VariantQueryProjection; +import org.opencb.opencga.storage.core.variant.query.projection.VariantQueryProjectionParser; import java.util.List; import java.util.Map; +import static org.opencb.opencga.storage.core.variant.adaptors.VariantQueryParam.SAMPLE_METADATA; + /** * Created on 07/02/17. * @@ -45,25 +50,19 @@ public class VariantQueryResult extends OpenCGAResult { private static final String APPROXIMATE_COUNT = "approximateCount"; private static final String APPROXIMATE_COUNT_SAMPLING_SIZE = "approximateCountSamplingSize"; - public VariantQueryResult() { - } - - public VariantQueryResult(long time, int numResults, long numMatches, List events, List result) { - this(time, numResults, numMatches, events, result, null, null, null, null, null); + protected VariantQueryResult() { } - public VariantQueryResult(long time, int numResults, long numMatches, List events, List result, - Map> samples, String source) { - this(time, numResults, numMatches, events, result, samples, source, null, null, null); + public VariantQueryResult(long time, int numResults, long numMatches, List events, List result, String source, + ParsedVariantQuery variantQuery) { + this(time, numResults, numMatches, events, result, source, null, null, null, variantQuery); } public VariantQueryResult(long time, int numResults, long numMatches, List events, List result, - Map> samples, String source, Boolean approximateCount, - Integer approximateCountSamplingSize, Integer numTotalSamples) { + String source, Boolean approximateCount, Integer approximateCountSamplingSize, Integer numTotalSamples, + ParsedVariantQuery variantQuery) { super((int) time, events, numResults, result, numMatches); - if (samples != null) { - setSamples(samples); - } + if (source != null) { setSource(source); } @@ -73,15 +72,15 @@ public VariantQueryResult(long time, int numResults, long numMatches, List) this, variantQuery); + } } - public VariantQueryResult(DataResult dataResult) { + private VariantQueryResult(DataResult dataResult, List results) { super(dataResult.getTime(), dataResult.getEvents(), dataResult.getNumMatches(), @@ -90,26 +89,65 @@ public VariantQueryResult(DataResult dataResult) { dataResult.getNumDeleted(), dataResult.getNumErrors(), dataResult.getAttributes()); - setResults(dataResult.getResults()); - setNumResults(dataResult.getNumResults()); + setResults(results); + setNumResults(results.size()); } - public VariantQueryResult(DataResult queryResult, Map> samples) { - this(queryResult, samples, null); + public VariantQueryResult(DataResult dataResult, ParsedVariantQuery variantQuery) { + this(dataResult, dataResult.getResults()); + if (variantQuery != null) { + addSamplesMetadataIfRequested((VariantQueryResult) this, variantQuery); + } } - public VariantQueryResult(DataResult dataResult, Map> samples, String source) { - this(dataResult); - setSamples(samples); - if (getNumMatches() >= 0) { - setApproximateCount(false); - } - if (samples != null) { - this.setNumSamples(samples.values().stream().mapToInt(List::size).sum()); - this.setNumTotalSamples(getNumSamples()); - } - if (source != null) { - this.setSource(source); + public VariantQueryResult(VariantQueryResult dataResult, List results) { + this((DataResult) dataResult, results); + } + + public VariantQueryResult(DataResult dataResult, String source, ParsedVariantQuery variantQuery) { + this(dataResult, variantQuery); + setSource(source); + } + + /* + * @deprecated Missing ParsedVariantQuery. + * Use {@link #VariantQueryResult(long, int, long, List, List, String, Boolean, Integer, Integer, ParsedVariantQuery)} + */ + @Deprecated + public VariantQueryResult(long time, int numResults, long numMatches, List events, List result, String source) { + this(time, numResults, numMatches, events, result, source, null, null, null, (ParsedVariantQuery) null); + } + + /* + * @deprecated Missing ParsedVariantQuery. + * Use {@link #VariantQueryResult(DataResult, ParsedVariantQuery)} + */ + @Deprecated + public VariantQueryResult(DataResult dataResult) { + this(dataResult, (ParsedVariantQuery) null); + } + + private static VariantQueryResult addSamplesMetadataIfRequested(VariantQueryResult result, ParsedVariantQuery query) { + VariantQueryProjection projection = query.getProjection(); + + int numTotalSamples = projection.getNumTotalSamples(); + int numSamples = projection.getNumSamples(); + if (query.getInputQuery().getBoolean(SAMPLE_METADATA.key(), false)) { + Map> samplesMetadata = query.getProjection().getSampleNames(); + if (numTotalSamples < 0 && numSamples < 0) { + numTotalSamples = samplesMetadata.values().stream().mapToInt(List::size).sum(); + VariantQueryProjectionParser.skipAndLimitSamples(query.getQuery(), samplesMetadata); + numSamples = samplesMetadata.values().stream().mapToInt(List::size).sum(); + } + return result.setNumSamples(numSamples) + .setNumTotalSamples(numTotalSamples) + .setSamples(samplesMetadata); + } else { + if (numTotalSamples >= 0 && numSamples >= 0) { + return result.setNumSamples(numSamples) + .setNumTotalSamples(numTotalSamples); + } + return result; } } @@ -173,7 +211,9 @@ public VariantQueryResult setApproximateCount(Boolean approximateCount) { } public Integer getApproximateCountSamplingSize() { - return getAttributes().containsKey(APPROXIMATE_COUNT_SAMPLING_SIZE) ? getAttributes().getInt(APPROXIMATE_COUNT_SAMPLING_SIZE) : null; + return getAttributes().containsKey(APPROXIMATE_COUNT_SAMPLING_SIZE) + ? getAttributes().getInt(APPROXIMATE_COUNT_SAMPLING_SIZE) + : null; } public VariantQueryResult setApproximateCountSamplingSize(Integer approximateCountSamplingSize) { diff --git a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/VariantQueryUtils.java b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/VariantQueryUtils.java index 114379c77a9..b4e2e7819d3 100644 --- a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/VariantQueryUtils.java +++ b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/VariantQueryUtils.java @@ -28,12 +28,13 @@ import org.opencb.biodata.models.variant.VariantBuilder; import org.opencb.biodata.models.variant.annotation.ConsequenceTypeMappings; import org.opencb.biodata.models.variant.avro.*; -import org.opencb.commons.datastore.core.*; +import org.opencb.commons.datastore.core.ObjectMap; +import org.opencb.commons.datastore.core.Query; +import org.opencb.commons.datastore.core.QueryOptions; +import org.opencb.commons.datastore.core.QueryParam; import org.opencb.commons.utils.ListUtils; import org.opencb.opencga.core.api.ParamConstants; import org.opencb.opencga.core.models.variant.VariantAnnotationConstants; -import org.opencb.opencga.core.response.VariantQueryResult; -import org.opencb.opencga.storage.core.metadata.VariantStorageMetadataManager; import org.opencb.opencga.storage.core.utils.CellBaseUtils; import org.opencb.opencga.storage.core.variant.adaptors.VariantField; import org.opencb.opencga.storage.core.variant.adaptors.VariantQueryException; @@ -583,37 +584,6 @@ public static boolean isOutputMultiStudy(Query query, QueryOptions options, Coll } } - public static VariantQueryResult addSamplesMetadataIfRequested(DataResult result, Query query, QueryOptions options, - VariantStorageMetadataManager variantStorageMetadataManager) { - return addSamplesMetadataIfRequested(new VariantQueryResult<>(result, null), query, options, variantStorageMetadataManager); - } - - public static VariantQueryResult addSamplesMetadataIfRequested(VariantQueryResult result, Query query, QueryOptions options, - VariantStorageMetadataManager variantStorageMetadataManager) { - if (query.getBoolean(SAMPLE_METADATA.key(), false)) { - int numTotalSamples = query.getInt(NUM_TOTAL_SAMPLES.key(), -1); - int numSamples = query.getInt(NUM_SAMPLES.key(), -1); - Map> samplesMetadata = VariantQueryProjectionParser - .getIncludeSampleNames(query, options, variantStorageMetadataManager); - if (numTotalSamples < 0 && numSamples < 0) { - numTotalSamples = samplesMetadata.values().stream().mapToInt(List::size).sum(); - VariantQueryProjectionParser.skipAndLimitSamples(query, samplesMetadata); - numSamples = samplesMetadata.values().stream().mapToInt(List::size).sum(); - } - return result.setNumSamples(numSamples) - .setNumTotalSamples(numTotalSamples) - .setSamples(samplesMetadata); - } else { - int numTotalSamples = query.getInt(NUM_TOTAL_SAMPLES.key(), -1); - int numSamples = query.getInt(NUM_SAMPLES.key(), -1); - if (numTotalSamples >= 0 && numSamples >= 0) { - return result.setNumSamples(numSamples) - .setNumTotalSamples(numTotalSamples); - } - return result; - } - } - /** * Gets a list of elements sample data keys to return. * diff --git a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/executors/AbstractTwoPhasedVariantQueryExecutor.java b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/executors/AbstractTwoPhasedVariantQueryExecutor.java index a49fe60c3e4..4a815959a84 100644 --- a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/executors/AbstractTwoPhasedVariantQueryExecutor.java +++ b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/executors/AbstractTwoPhasedVariantQueryExecutor.java @@ -7,7 +7,7 @@ import org.opencb.commons.datastore.core.Query; import org.opencb.commons.datastore.core.QueryOptions; import org.opencb.opencga.core.common.TimeUtils; -import org.opencb.opencga.core.response.VariantQueryResult; +import org.opencb.opencga.storage.core.variant.query.VariantQueryResult; import org.opencb.opencga.storage.core.metadata.VariantStorageMetadataManager; import org.opencb.opencga.storage.core.variant.VariantStorageOptions; import org.opencb.opencga.storage.core.variant.adaptors.iterators.VariantDBIteratorWithCounts; diff --git a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/executors/BreakendVariantQueryExecutor.java b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/executors/BreakendVariantQueryExecutor.java index 0e8c9ead98c..6eb237ea4b3 100644 --- a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/executors/BreakendVariantQueryExecutor.java +++ b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/executors/BreakendVariantQueryExecutor.java @@ -1,6 +1,5 @@ package org.opencb.opencga.storage.core.variant.query.executors; -import com.google.common.collect.Iterators; import org.apache.commons.lang3.StringUtils; import org.opencb.biodata.models.core.Region; import org.opencb.biodata.models.variant.StudyEntry; @@ -13,14 +12,13 @@ import org.opencb.commons.datastore.core.Query; import org.opencb.commons.datastore.core.QueryOptions; import org.opencb.commons.datastore.core.QueryParam; -import org.opencb.opencga.core.response.VariantQueryResult; import org.opencb.opencga.storage.core.exceptions.StorageEngineException; -import org.opencb.opencga.storage.core.metadata.VariantStorageMetadataManager; -import org.opencb.opencga.storage.core.variant.VariantStorageOptions; import org.opencb.opencga.storage.core.variant.adaptors.VariantDBAdaptor; import org.opencb.opencga.storage.core.variant.adaptors.VariantQueryException; import org.opencb.opencga.storage.core.variant.adaptors.VariantQueryParam; import org.opencb.opencga.storage.core.variant.adaptors.iterators.VariantDBIterator; +import org.opencb.opencga.storage.core.variant.query.ParsedVariantQuery; +import org.opencb.opencga.storage.core.variant.query.VariantQueryResult; import org.opencb.opencga.storage.core.variant.query.VariantQueryUtils; import org.opencb.opencga.storage.core.variant.query.filters.VariantFilterBuilder; @@ -33,12 +31,12 @@ public class BreakendVariantQueryExecutor extends VariantQueryExecutor { private final VariantDBAdaptor variantDBAdaptor; private final VariantFilterBuilder filterBuilder; - public BreakendVariantQueryExecutor(VariantStorageMetadataManager metadataManager, String storageEngineId, ObjectMap options, + public BreakendVariantQueryExecutor(String storageEngineId, ObjectMap options, VariantQueryExecutor delegatedQueryExecutor, VariantDBAdaptor variantDBAdaptor) { - super(metadataManager, storageEngineId, options); + super(variantDBAdaptor.getMetadataManager(), storageEngineId, options); this.delegatedQueryExecutor = delegatedQueryExecutor; this.variantDBAdaptor = variantDBAdaptor; - filterBuilder = new VariantFilterBuilder(metadataManager); + filterBuilder = new VariantFilterBuilder(); } @Override @@ -48,35 +46,39 @@ public boolean canUseThisExecutor(Query query, QueryOptions options) throws Stor } @Override - protected Object getOrIterator(Query query, QueryOptions options, boolean getIterator) throws StorageEngineException { - int limit = options.getInt(QueryOptions.LIMIT); - int skip = options.getInt(QueryOptions.SKIP); - boolean count = options.getBoolean(QueryOptions.COUNT); - int approximateCountSamplingSize = options.getInt( - VariantStorageOptions.APPROXIMATE_COUNT_SAMPLING_SIZE.key(), - VariantStorageOptions.APPROXIMATE_COUNT_SAMPLING_SIZE.defaultValue()); - Query baseQuery = baseQuery(query); - Predicate variantLocalFilter = filterBuilder.buildFilter(query, options); - + protected Object getOrIterator(ParsedVariantQuery variantQuery, boolean getIterator) throws StorageEngineException { + int limit = variantQuery.getLimitOr(-1); + int skip = variantQuery.getSkip(); + boolean count = variantQuery.getCount() && !getIterator; + int approximateCountSamplingSize = variantQuery.getApproximateCountSamplingSize(); + Query baseQuery = baseQuery(variantQuery.getQuery()); + Predicate variantLocalFilter = filterBuilder.buildFilter(variantQuery); + + // Copy to avoid modifications to input query + ParsedVariantQuery delegatedVariantQuery = new ParsedVariantQuery(variantQuery); + QueryOptions options = new QueryOptions(variantQuery.getInputOptions()); + options.remove(QueryOptions.SKIP); + delegatedVariantQuery.setSkip(0); + if (limit >= 0) { + int tmpLimit = skip + limit * 4; + if (count && tmpLimit < approximateCountSamplingSize) { + tmpLimit = approximateCountSamplingSize; + } + options.put(QueryOptions.LIMIT, tmpLimit); + delegatedVariantQuery.setLimit(tmpLimit); + } + delegatedVariantQuery.setInputOptions(options); if (getIterator) { - VariantDBIterator iterator = delegatedQueryExecutor.iterator(query, options); + VariantDBIterator iterator = delegatedQueryExecutor.iterator(delegatedVariantQuery); iterator = iterator.mapBuffered(l -> getBreakendPairs(0, baseQuery, variantLocalFilter, l), 100); iterator = iterator.localLimitSkip(limit, skip); return iterator; } else { - // Copy to avoid modifications to input options - options = new QueryOptions(options); - options.remove(QueryOptions.SKIP); - int tmpLimit = skip + limit * 2; - if (count && tmpLimit < approximateCountSamplingSize) { - tmpLimit = approximateCountSamplingSize; - } - options.put(QueryOptions.LIMIT, tmpLimit); - VariantQueryResult queryResult = delegatedQueryExecutor.get(query, options); + VariantQueryResult queryResult = delegatedQueryExecutor.get(delegatedVariantQuery); List results = queryResult.getResults(); results = getBreakendPairs(0, baseQuery, variantLocalFilter, results); - if (queryResult.getNumMatches() < tmpLimit) { + if (queryResult.getNumMatches() < delegatedVariantQuery.getLimitOr(-1)) { // Exact count!! queryResult.setApproximateCount(false); queryResult.setNumMatches(results.size()); @@ -100,24 +102,6 @@ protected Object getOrIterator(Query query, QueryOptions options, boolean getIte } } - - protected VariantDBIterator iterator(Query query, QueryOptions options, int batchSize) throws StorageEngineException { - - int limit = options.getInt(QueryOptions.LIMIT); - int skip = options.getInt(QueryOptions.SKIP); - Query baseQuery = baseQuery(query); - Predicate variantLocalFilter = filterBuilder.buildFilter(query, options); - - VariantDBIterator iterator = delegatedQueryExecutor.iterator(query, options); - iterator = iterator.mapBuffered(l -> getBreakendPairs(0, baseQuery, variantLocalFilter, l), batchSize); - Iterators.advance(iterator, skip); - iterator = iterator.localSkip(skip); - if (limit > 0) { - iterator = iterator.localLimit(limit); - } - return iterator; - } - private Query baseQuery(Query query) { return subQuery(query, VariantQueryParam.STUDY, @@ -143,7 +127,6 @@ private List getBreakendPairs(int samplePosition, Query baseQuery, Pred } // Copy query to avoid propagating modifications baseQuery = new Query(baseQuery); -// System.out.println("variants = " + variants); List regions = new ArrayList<>(variants.size()); for (Variant variant : variants) { BreakendMate mate = variant.getSv().getBreakend().getMate(); @@ -190,7 +173,7 @@ private List getBreakendPairs(int samplePosition, Query baseQuery, Pred return variantPairs; } - private void addPair(Predicate filter, List variantPairs, Variant variant, Variant mateVariant) { + private boolean addPair(Predicate filter, List variantPairs, Variant variant, Variant mateVariant) { // Check for duplicated pairs if (VariantDBIterator.VARIANT_COMPARATOR.compare(variant, mateVariant) > 0) { // The mate variant is "before" the main variant @@ -200,10 +183,14 @@ private void addPair(Predicate filter, List variantPairs, Vari // But first the "mate" to respect order variantPairs.add(mateVariant); variantPairs.add(variant); + return true; + } else { + return false; } } else { variantPairs.add(variant); variantPairs.add(mateVariant); + return true; } } diff --git a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/executors/ChromDensityVariantAggregationExecutor.java b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/executors/ChromDensityVariantAggregationExecutor.java index b7a03ceac34..9606a74a85d 100644 --- a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/executors/ChromDensityVariantAggregationExecutor.java +++ b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/executors/ChromDensityVariantAggregationExecutor.java @@ -8,7 +8,7 @@ import org.opencb.commons.datastore.core.Query; import org.opencb.commons.datastore.core.QueryOptions; import org.opencb.commons.datastore.solr.FacetQueryParser; -import org.opencb.opencga.core.response.VariantQueryResult; +import org.opencb.opencga.storage.core.variant.query.VariantQueryResult; import org.opencb.opencga.storage.core.metadata.VariantStorageMetadataManager; import org.opencb.opencga.storage.core.variant.adaptors.VariantField; import org.opencb.opencga.storage.core.variant.adaptors.VariantIterable; @@ -144,7 +144,7 @@ protected VariantQueryResult aggregation(Query query, QueryOptions o regionBuckets.size(), regionBuckets); return new VariantQueryResult<>((int) stopWatch.getTime(TimeUnit.MILLISECONDS), 1, numMatches, Collections.emptyList(), - Collections.singletonList(field), null, null); + Collections.singletonList(field), null); } private VariantQueryException invalidNestedField(String nestedFieldName) { diff --git a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/executors/CompoundHeterozygousQueryExecutor.java b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/executors/CompoundHeterozygousQueryExecutor.java index db0815b5135..c6f4b87a5f0 100644 --- a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/executors/CompoundHeterozygousQueryExecutor.java +++ b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/executors/CompoundHeterozygousQueryExecutor.java @@ -3,21 +3,24 @@ import com.google.common.collect.Iterators; import org.opencb.biodata.models.variant.Variant; import org.opencb.biodata.tools.pedigree.ModeOfInheritance; -import org.opencb.opencga.core.models.variant.VariantAnnotationConstants; -import org.opencb.commons.datastore.core.DataResult; import org.opencb.commons.datastore.core.ObjectMap; import org.opencb.commons.datastore.core.Query; import org.opencb.commons.datastore.core.QueryOptions; -import org.opencb.opencga.core.response.VariantQueryResult; +import org.opencb.opencga.core.models.variant.VariantAnnotationConstants; import org.opencb.opencga.storage.core.exceptions.StorageEngineException; import org.opencb.opencga.storage.core.metadata.VariantStorageMetadataManager; import org.opencb.opencga.storage.core.metadata.models.SampleMetadata; import org.opencb.opencga.storage.core.metadata.models.Trio; import org.opencb.opencga.storage.core.variant.VariantStorageOptions; -import org.opencb.opencga.storage.core.variant.adaptors.*; +import org.opencb.opencga.storage.core.variant.adaptors.VariantField; +import org.opencb.opencga.storage.core.variant.adaptors.VariantIterable; +import org.opencb.opencga.storage.core.variant.adaptors.VariantQueryException; +import org.opencb.opencga.storage.core.variant.adaptors.VariantQueryParam; import org.opencb.opencga.storage.core.variant.adaptors.iterators.UnionMultiVariantKeyIterator; import org.opencb.opencga.storage.core.variant.adaptors.iterators.VariantDBIterator; import org.opencb.opencga.storage.core.variant.adaptors.iterators.VariantDBIteratorWithCounts; +import org.opencb.opencga.storage.core.variant.query.ParsedVariantQuery; +import org.opencb.opencga.storage.core.variant.query.VariantQueryResult; import org.opencb.opencga.storage.core.variant.query.VariantQueryUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -66,15 +69,11 @@ public boolean canUseThisExecutor(Query query, QueryOptions options) throws Stor } @Override - public DataResult count(Query query) { - throw new UnsupportedOperationException(); - } - - @Override - protected Object getOrIterator(Query query, QueryOptions options, boolean iterator) { - Trio trio = getCompHetTrio(query); - return getOrIterator(query.getString(VariantQueryParam.STUDY.key()), trio.getChild(), trio.getFather(), trio.getMother(), - query, options, iterator); + protected Object getOrIterator(ParsedVariantQuery variantQuery, boolean iterator) { + Trio trio = getCompHetTrio(variantQuery.getQuery()); + String study = variantQuery.getStudyQuery().getStudyOrFail(); + return getOrIterator(study, trio.getChild(), trio.getFather(), trio.getMother(), + variantQuery, iterator); } @Override @@ -84,25 +83,25 @@ protected long primaryCount(Query query, QueryOptions options) { .append(QueryOptions.INCLUDE, VariantField.ID.fieldName()))); } - public VariantQueryResult get(String study, String proband, String father, String mother, Query query, QueryOptions options) { - return (VariantQueryResult) getOrIterator(study, proband, father, mother, query, options, false); + public VariantQueryResult get(String study, String proband, String father, String mother, ParsedVariantQuery variantQuery) { + return (VariantQueryResult) getOrIterator(study, proband, father, mother, variantQuery, false); } - public VariantDBIterator iterator(String study, String proband, String father, String mother, Query query, QueryOptions options) { - return (VariantDBIterator) getOrIterator(study, proband, father, mother, query, options, true); + public VariantDBIterator iterator(String study, String proband, String father, String mother, ParsedVariantQuery variantQuery) { + return (VariantDBIterator) getOrIterator(study, proband, father, mother, variantQuery, true); } - private Object getOrIterator(String study, String proband, String father, String mother, Query query, QueryOptions inputOptions, + private Object getOrIterator(String study, String proband, String father, String mother, ParsedVariantQuery variantQuery, boolean iterator) { // Prepare query and options - int skip = getSkip(inputOptions); - int limit = inputOptions.containsKey(QueryOptions.LIMIT) ? getLimit(inputOptions) : (Integer.MAX_VALUE - skip); - int samplingSize = getSamplingSize(inputOptions, DEFAULT_SAMPLING_SIZE, iterator); - QueryOptions options = buildQueryOptions(inputOptions); + int skip = variantQuery.getSkip(); + int limit = variantQuery.getLimit() != null ? variantQuery.getLimit() : (Integer.MAX_VALUE - skip); + int samplingSize = getSamplingSize(variantQuery.getInputOptions(), DEFAULT_SAMPLING_SIZE, iterator); + QueryOptions options = buildQueryOptions(variantQuery.getInputOptions()); // Always sort results for compound heterozygous options.put(QueryOptions.SORT, true); - query = new Query(query); + Query query = new Query(variantQuery.getQuery()); List includeSample = getAndCheckIncludeSample(query, proband, father, mother); Set biotypes; @@ -158,12 +157,12 @@ private Object getOrIterator(String study, String proband, String father, String return VariantDBIterator.wrapper(variantIterator); } else { VariantQueryResult result = VariantDBIterator.wrapper(variantIterator) - .toDataResult(Collections.singletonMap(study, includeSample)); + .toDataResult(variantQuery); if ((limit + skip) < samplingSize && compoundHeterozygous.size() < samplingSize) { result.setApproximateCount(false); result.setNumMatches(compoundHeterozygous.size()); } else { - setNumTotalResults(unfilteredIterator, result, query, inputOptions, + setNumTotalResults(unfilteredIterator, result, query, variantQuery.getInputOptions(), unfilteredIterator.getCount(), compoundHeterozygous.size()); } diff --git a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/executors/DBAdaptorVariantQueryExecutor.java b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/executors/DBAdaptorVariantQueryExecutor.java index 08705ccf69e..474cbc3fa9f 100644 --- a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/executors/DBAdaptorVariantQueryExecutor.java +++ b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/executors/DBAdaptorVariantQueryExecutor.java @@ -2,7 +2,9 @@ import org.opencb.biodata.models.variant.Variant; import org.opencb.commons.datastore.core.*; -import org.opencb.opencga.core.response.VariantQueryResult; +import org.opencb.opencga.storage.core.exceptions.StorageEngineException; +import org.opencb.opencga.storage.core.variant.query.ParsedVariantQuery; +import org.opencb.opencga.storage.core.variant.query.VariantQueryResult; import org.opencb.opencga.storage.core.variant.adaptors.VariantDBAdaptor; import org.opencb.opencga.storage.core.variant.adaptors.VariantQueryParam; import org.opencb.opencga.storage.core.variant.query.VariantQueryUtils; @@ -37,11 +39,11 @@ public DBAdaptorVariantQueryExecutor(VariantDBAdaptor dbAdaptor, String storageE } @Override - protected Object getOrIterator(Query query, QueryOptions options, boolean iterator) { + protected Object getOrIterator(ParsedVariantQuery variantQuery, boolean iterator) throws StorageEngineException { if (iterator) { - return dbAdaptor.iterator(query, options); + return dbAdaptor.iterator(variantQuery); } else { - VariantQueryResult result = dbAdaptor.get(query, options); + VariantQueryResult result = dbAdaptor.get(variantQuery); if (result.getSource() == null || result.getSource().isEmpty()) { result.setSource(storageEngineId); } @@ -49,11 +51,6 @@ protected Object getOrIterator(Query query, QueryOptions options, boolean iterat } } - @Override - public DataResult count(Query query) { - return dbAdaptor.count(query); - } - @Override public boolean canUseThisExecutor(Query query, QueryOptions options) { for (QueryParam unsupportedParam : UNSUPPORTED_PARAMS) { diff --git a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/executors/NoOpVariantQueryExecutor.java b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/executors/NoOpVariantQueryExecutor.java index 57b1e64ae58..e286b4a07ce 100644 --- a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/executors/NoOpVariantQueryExecutor.java +++ b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/executors/NoOpVariantQueryExecutor.java @@ -1,10 +1,8 @@ package org.opencb.opencga.storage.core.variant.query.executors; -import org.opencb.biodata.models.variant.Variant; import org.opencb.commons.datastore.core.ObjectMap; import org.opencb.commons.datastore.core.Query; import org.opencb.commons.datastore.core.QueryOptions; -import org.opencb.opencga.core.response.VariantQueryResult; import org.opencb.opencga.storage.core.exceptions.StorageEngineException; import org.opencb.opencga.storage.core.metadata.VariantStorageMetadataManager; import org.opencb.opencga.storage.core.metadata.models.CohortMetadata; @@ -126,14 +124,11 @@ private boolean checkStatsFilter(Query query, String sample, VariantQueryParam p } @Override - protected Object getOrIterator(Query query, QueryOptions options, boolean iterator) throws StorageEngineException { + protected Object getOrIterator(ParsedVariantQuery variantQuery, boolean iterator) throws StorageEngineException { if (iterator) { return VariantDBIterator.emptyIterator(); } else { - VariantQueryResult result = new VariantQueryResult<>(0, 0, 0, Collections.emptyList(), Collections.emptyList()); - result.setSource(NO_OP); - VariantQueryUtils.addSamplesMetadataIfRequested(result, query, options, metadataManager); - return result; + return new VariantQueryResult<>(0, 0, 0, Collections.emptyList(), Collections.emptyList(), NO_OP, variantQuery); } } } diff --git a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/executors/VariantAggregationExecutor.java b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/executors/VariantAggregationExecutor.java index a2c7f67d54e..8479dd683f7 100644 --- a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/executors/VariantAggregationExecutor.java +++ b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/executors/VariantAggregationExecutor.java @@ -4,7 +4,7 @@ import org.opencb.commons.datastore.core.FacetField; import org.opencb.commons.datastore.core.Query; import org.opencb.commons.datastore.core.QueryOptions; -import org.opencb.opencga.core.response.VariantQueryResult; +import org.opencb.opencga.storage.core.variant.query.VariantQueryResult; import org.opencb.opencga.storage.core.variant.adaptors.VariantQueryException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/executors/VariantQueryExecutor.java b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/executors/VariantQueryExecutor.java index 8e445cc30e2..26d53e89e5c 100644 --- a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/executors/VariantQueryExecutor.java +++ b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/executors/VariantQueryExecutor.java @@ -1,18 +1,15 @@ package org.opencb.opencga.storage.core.variant.query.executors; import org.opencb.biodata.models.variant.Variant; -import org.opencb.commons.datastore.core.DataResult; import org.opencb.commons.datastore.core.ObjectMap; import org.opencb.commons.datastore.core.Query; import org.opencb.commons.datastore.core.QueryOptions; -import org.opencb.opencga.core.response.VariantQueryResult; import org.opencb.opencga.storage.core.exceptions.StorageEngineException; import org.opencb.opencga.storage.core.metadata.VariantStorageMetadataManager; -import org.opencb.opencga.storage.core.variant.adaptors.VariantIterable; import org.opencb.opencga.storage.core.variant.adaptors.VariantQueryException; import org.opencb.opencga.storage.core.variant.adaptors.iterators.VariantDBIterator; - -import java.util.Collections; +import org.opencb.opencga.storage.core.variant.query.ParsedVariantQuery; +import org.opencb.opencga.storage.core.variant.query.VariantQueryResult; import static org.opencb.opencga.storage.core.variant.VariantStorageOptions.QUERY_DEFAULT_TIMEOUT; import static org.opencb.opencga.storage.core.variant.VariantStorageOptions.QUERY_MAX_TIMEOUT; @@ -22,7 +19,7 @@ * * @author Jacobo Coll <jacobo167@gmail.com> */ -public abstract class VariantQueryExecutor implements VariantIterable { +public abstract class VariantQueryExecutor { protected final VariantStorageMetadataManager metadataManager; protected final String storageEngineId; @@ -34,19 +31,17 @@ public VariantQueryExecutor(VariantStorageMetadataManager metadataManager, Strin this.options = options; } - public final VariantQueryResult get(Query query, QueryOptions options) { + public final VariantQueryResult get(ParsedVariantQuery query) { try { - return (VariantQueryResult) getOrIterator(query, options, false); + return (VariantQueryResult) getOrIterator(query, false); } catch (StorageEngineException e) { throw VariantQueryException.internalException(e); } } - @Override - public final VariantDBIterator iterator(Query query, QueryOptions options) { + public final VariantDBIterator iterator(ParsedVariantQuery variantQuery) { try { -// query = parser.preProcessQuery(query, options); - return (VariantDBIterator) getOrIterator(query, options, true); + return (VariantDBIterator) getOrIterator(variantQuery, true); } catch (StorageEngineException e) { throw VariantQueryException.internalException(e); } @@ -77,19 +72,7 @@ public static void setDefaultTimeout(QueryOptions queryOptions, ObjectMap config */ public abstract boolean canUseThisExecutor(Query query, QueryOptions options) throws StorageEngineException; - @Deprecated - public DataResult count(Query query) { - VariantQueryResult result = get(query, new QueryOptions(QueryOptions.COUNT, true).append(QueryOptions.LIMIT, 0)); - return new DataResult<>( - result.getTime(), - result.getEvents(), - 1, - Collections.singletonList(result.getNumMatches()), - result.getNumMatches(), - result.getAttributes()); - } - - protected abstract Object getOrIterator(Query query, QueryOptions options, boolean iterator) throws StorageEngineException; + protected abstract Object getOrIterator(ParsedVariantQuery variantQuery, boolean iterator) throws StorageEngineException; protected VariantStorageMetadataManager getMetadataManager() { return metadataManager; diff --git a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/filters/VariantFilterBuilder.java b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/filters/VariantFilterBuilder.java index f8705d26eef..1f505864fd1 100644 --- a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/filters/VariantFilterBuilder.java +++ b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/filters/VariantFilterBuilder.java @@ -5,32 +5,26 @@ import org.opencb.biodata.models.variant.Variant; import org.opencb.biodata.models.variant.avro.ConsequenceType; import org.opencb.biodata.models.variant.avro.SequenceOntologyTerm; -import org.opencb.commons.datastore.core.Query; -import org.opencb.commons.datastore.core.QueryOptions; -import org.opencb.opencga.storage.core.metadata.VariantStorageMetadataManager; -import org.opencb.opencga.storage.core.variant.adaptors.VariantQueryParam; -import org.opencb.opencga.storage.core.variant.query.*; +import org.opencb.opencga.storage.core.variant.query.KeyOpValue; +import org.opencb.opencga.storage.core.variant.query.ParsedQuery; +import org.opencb.opencga.storage.core.variant.query.ParsedVariantQuery; +import org.opencb.opencga.storage.core.variant.query.VariantQueryUtils; import java.util.*; import java.util.function.Predicate; import java.util.stream.Collectors; -import static org.opencb.opencga.storage.core.variant.adaptors.VariantQueryParam.*; - public class VariantFilterBuilder { - private final VariantStorageMetadataManager metadataManager; - - public VariantFilterBuilder(VariantStorageMetadataManager metadataManager) { - this.metadataManager = metadataManager; + public VariantFilterBuilder() { } - public Predicate buildFilter(Query query, QueryOptions queryOptions) { + public Predicate buildFilter(ParsedVariantQuery variantQuery) { List> filters = new LinkedList<>(); - addRegionFilters(query, filters); - addAnnotationFilters(query, filters); + addRegionFilters(variantQuery, filters); + addAnnotationFilters(variantQuery, filters); if (filters.isEmpty()) { return v -> true; @@ -39,18 +33,18 @@ public Predicate buildFilter(Query query, QueryOptions queryOptions) { } } - private void addRegionFilters(Query query, List> filters) { + private void addRegionFilters(ParsedVariantQuery variantQuery, List> filters) { List> regionFilters = new LinkedList<>(); - if (VariantQueryUtils.isValidParam(query, VariantQueryParam.REGION)) { - List regions = Region.parseRegions(query.getString(REGION.key()), true); + List regions = variantQuery.getRegions(); + if (!regions.isEmpty()) { regions = VariantQueryUtils.mergeRegions(regions); for (Region region : regions) { regionFilters.add(variant -> region.contains(variant.getChromosome(), variant.getStart())); } } - ParsedVariantQuery.VariantQueryXref variantQueryXref = VariantQueryParser.parseXrefs(query); - Predicate geneFilter = getGeneFilter(query, variantQueryXref.getGenes()); + ParsedVariantQuery.VariantQueryXref variantQueryXref = variantQuery.getXrefs(); + Predicate geneFilter = getGeneFilter(variantQuery, variantQueryXref.getGenes()); if (!variantQueryXref.getIds().isEmpty()) { Set ids = new HashSet<>(variantQueryXref.getIds()); regionFilters.add(variant -> ids.contains(variant.getAnnotation().getId())); @@ -65,15 +59,14 @@ private void addRegionFilters(Query query, List> filters) { if (!regionFilters.isEmpty()) { Set bts; - if (VariantQueryUtils.isValidParam(query, VariantQueryParam.ANNOT_BIOTYPE)) { - bts = new HashSet<>(query.getAsStringList(VariantQueryParam.ANNOT_BIOTYPE.key())); + if (!variantQuery.getBiotypes().isEmpty()) { + bts = new HashSet<>(variantQuery.getBiotypes()); } else { bts = null; } Set cts; - if (VariantQueryUtils.isValidParam(query, VariantQueryParam.ANNOT_CONSEQUENCE_TYPE)) { - cts = new HashSet<>(VariantQueryUtils - .parseConsequenceTypes(query.getAsStringList(VariantQueryParam.ANNOT_CONSEQUENCE_TYPE.key()))); + if (!variantQuery.getConsequenceTypes().isEmpty()) { + cts = new HashSet<>(variantQuery.getConsequenceTypes()); } else { cts = null; } @@ -99,12 +92,12 @@ private void addRegionFilters(Query query, List> filters) { } } - private Predicate getGeneFilter(Query query, List genes) { + private Predicate getGeneFilter(ParsedVariantQuery variantQuery, List genes) { if (genes.isEmpty()) { return null; } - List geneRegions = Region.parseRegions(query.getString(VariantQueryUtils.ANNOT_GENE_REGIONS.key())); + List geneRegions = variantQuery.getGeneRegions(); Predicate geneRegionFilter; if (CollectionUtils.isEmpty(geneRegions)) { geneRegionFilter = null; @@ -115,15 +108,14 @@ private Predicate getGeneFilter(Query query, List genes) { Predicate geneFilter; Set bts; - if (VariantQueryUtils.isValidParam(query, VariantQueryParam.ANNOT_BIOTYPE)) { - bts = new HashSet<>(query.getAsStringList(VariantQueryParam.ANNOT_BIOTYPE.key())); + if (!variantQuery.getBiotypes().isEmpty()) { + bts = new HashSet<>(variantQuery.getBiotypes()); } else { bts = null; } Set cts; - if (VariantQueryUtils.isValidParam(query, VariantQueryParam.ANNOT_CONSEQUENCE_TYPE)) { - cts = new HashSet<>(VariantQueryUtils - .parseConsequenceTypes(query.getAsStringList(VariantQueryParam.ANNOT_CONSEQUENCE_TYPE.key()))); + if (!variantQuery.getConsequenceTypes().isEmpty()) { + cts = new HashSet<>(variantQuery.getConsequenceTypes()); } else { cts = null; } @@ -151,31 +143,30 @@ private Predicate getGeneFilter(Query query, List genes) { } } - private void addAnnotationFilters(Query query, List> filters) { -// ParsedVariantQuery.VariantQueryXref variantQueryXref = VariantQueryParser.parseXrefs(query); - addClinicalFilters(query, filters); + private void addAnnotationFilters(ParsedVariantQuery variantQuery, List> filters) { +// ParsedVariantQuery.VariantQueryXref variantQueryXref = variantQuery.getXrefs(); + addClinicalFilters(variantQuery, filters); - if (VariantQueryUtils.isValidParam(query, ANNOT_POPULATION_ALTERNATE_FREQUENCY)) { - ParsedQuery> freqQuery - = VariantQueryParser.parseFreqFilter(query, ANNOT_POPULATION_ALTERNATE_FREQUENCY); + ParsedQuery> freqQuery = variantQuery.getPopulationFrequencyAlt(); + if (!freqQuery.isEmpty()) { List freqFilters = freqQuery.mapValues(popFreq -> { String[] split = popFreq.getKey().split(VariantQueryUtils.STUDY_POP_FREQ_SEPARATOR); return new PopulationFrequencyVariantFilter.AltFreqFilter(split[0], split[1], popFreq.getOp(), popFreq.getValue()); }); filters.add(new PopulationFrequencyVariantFilter(freqQuery.getOperation(), freqFilters)); } - if (VariantQueryUtils.isValidParam(query, ANNOT_POPULATION_REFERENCE_FREQUENCY)) { - ParsedQuery> freqQuery - = VariantQueryParser.parseFreqFilter(query, ANNOT_POPULATION_REFERENCE_FREQUENCY); + + freqQuery = variantQuery.getPopulationFrequencyRef(); + if (!freqQuery.isEmpty()) { List freqFilters = freqQuery.mapValues(popFreq -> { String[] split = popFreq.getKey().split(VariantQueryUtils.STUDY_POP_FREQ_SEPARATOR); return new PopulationFrequencyVariantFilter.RefFreqFilter(split[0], split[1], popFreq.getOp(), popFreq.getValue()); }); filters.add(new PopulationFrequencyVariantFilter(freqQuery.getOperation(), freqFilters)); } - if (VariantQueryUtils.isValidParam(query, ANNOT_POPULATION_MINOR_ALLELE_FREQUENCY)) { - ParsedQuery> freqQuery - = VariantQueryParser.parseFreqFilter(query, ANNOT_POPULATION_MINOR_ALLELE_FREQUENCY); + + freqQuery = variantQuery.getPopulationFrequencyMaf(); + if (!freqQuery.isEmpty()) { List freqFilters = freqQuery.mapValues(popFreq -> { String[] split = popFreq.getKey().split(VariantQueryUtils.STUDY_POP_FREQ_SEPARATOR); return new PopulationFrequencyVariantFilter.MafFreqFilter(split[0], split[1], popFreq.getOp(), popFreq.getValue()); @@ -185,8 +176,8 @@ private void addAnnotationFilters(Query query, List> filters) } - private void addClinicalFilters(Query query, List> filters) { - List> clinicalCombinations = VariantQueryParser.parseClinicalCombination(query) + private void addClinicalFilters(ParsedVariantQuery variantQuery, List> filters) { + List> clinicalCombinations = variantQuery.getClinicalCombinations() .stream().map(HashSet::new).collect(Collectors.toList()); if (clinicalCombinations.isEmpty()) { return; diff --git a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/projection/VariantQueryProjection.java b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/projection/VariantQueryProjection.java index 717967cc038..16b974ee57e 100644 --- a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/projection/VariantQueryProjection.java +++ b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/projection/VariantQueryProjection.java @@ -77,6 +77,10 @@ public Map> getSamples() { return studies.values().stream().collect(Collectors.toMap(s -> s.studyMetadata.getId(), s -> s.samples)); } + public Map> getSampleNames() { + return studies.values().stream().collect(Collectors.toMap(s -> s.studyMetadata.getName(), s -> s.sampleNames)); + } + @Deprecated public Map> getFiles() { return studies.values().stream().collect(Collectors.toMap(s -> s.studyMetadata.getId(), s -> s.files)); @@ -85,6 +89,7 @@ public Map> getFiles() { public static class StudyVariantQueryProjection { private StudyMetadata studyMetadata; private List samples = Collections.emptyList(); + private List sampleNames = Collections.emptyList(); private Map> multiFileSampleFiles = Collections.emptyMap(); private Set multiFileSamples = Collections.emptySet(); private List files = Collections.emptyList(); @@ -129,6 +134,15 @@ public StudyVariantQueryProjection setSamples(List samples) { return this; } + public List getSampleNames() { + return sampleNames; + } + + public StudyVariantQueryProjection setSampleNames(List sampleNames) { + this.sampleNames = sampleNames; + return this; + } + public Map> getMultiFileSampleFiles() { return multiFileSampleFiles; } diff --git a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/projection/VariantQueryProjectionParser.java b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/projection/VariantQueryProjectionParser.java index 0860aa87a4d..4ec7f2ec158 100644 --- a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/projection/VariantQueryProjectionParser.java +++ b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/projection/VariantQueryProjectionParser.java @@ -69,7 +69,13 @@ public VariantQueryProjection parseVariantQueryProjection(Query query, QueryOpti Map> sampleIdsMap = getIncludeSampleIds(query, options, includeStudies, metadataManager); for (VariantQueryProjection.StudyVariantQueryProjection study : studies.values()) { - study.setSamples(sampleIdsMap.get(study.getId())); + List sampleIds = sampleIdsMap.get(study.getId()); + study.setSamples(sampleIds); + List sampleNames = new ArrayList<>(sampleIds.size()); + for (Integer sampleId : sampleIds) { + sampleNames.add(metadataManager.getSampleName(study.getId(), sampleId)); + } + study.setSampleNames(sampleNames); } int numTotalSamples = sampleIdsMap.values().stream().mapToInt(List::size).sum(); skipAndLimitSamples(query, sampleIdsMap); @@ -478,6 +484,10 @@ public static boolean isIncludeSamplesDefined(Query query, Set fie return getIncludeSamplePartialStatus(query, fields) != null || getIncludeFilePartialStatus(query, fields) != null; } + /* + * @deprecated use VariantQueryProjection.getSampleNames() + */ + @Deprecated public static Map> getIncludeSampleNames(Query query, QueryOptions options, VariantStorageMetadataManager metadataManager) { if (VariantField.getIncludeFields(options).contains(VariantField.STUDIES)) { diff --git a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/search/SamplesSearchIndexVariantQueryExecutor.java b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/search/SamplesSearchIndexVariantQueryExecutor.java index dc278d1e3db..200b2eb463d 100644 --- a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/search/SamplesSearchIndexVariantQueryExecutor.java +++ b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/search/SamplesSearchIndexVariantQueryExecutor.java @@ -1,7 +1,5 @@ package org.opencb.opencga.storage.core.variant.search; -import org.apache.commons.lang3.time.StopWatch; -import org.opencb.commons.datastore.core.DataResult; import org.opencb.commons.datastore.core.ObjectMap; import org.opencb.commons.datastore.core.Query; import org.opencb.commons.datastore.core.QueryOptions; @@ -10,11 +8,10 @@ import org.opencb.opencga.storage.core.exceptions.VariantSearchException; import org.opencb.opencga.storage.core.variant.adaptors.VariantDBAdaptor; import org.opencb.opencga.storage.core.variant.adaptors.VariantQueryException; +import org.opencb.opencga.storage.core.variant.query.ParsedVariantQuery; import org.opencb.opencga.storage.core.variant.search.solr.VariantSearchManager; import java.io.IOException; -import java.util.Collections; -import java.util.concurrent.TimeUnit; import static org.opencb.opencga.storage.core.variant.search.VariantSearchUtils.inferSpecificSearchIndexSamplesCollection; @@ -37,19 +34,9 @@ public boolean canUseThisExecutor(Query query, QueryOptions options) throws Stor } @Override - public DataResult count(Query query) { - try { - StopWatch watch = StopWatch.createStarted(); - long count = searchManager.count(dbName, query); - int time = (int) watch.getTime(TimeUnit.MILLISECONDS); - return new DataResult<>(time, Collections.emptyList(), 1, Collections.singletonList(count), 1); - } catch (IOException | VariantSearchException e) { - throw new VariantQueryException("Error querying Solr", e); - } - } - - @Override - protected Object getOrIterator(Query query, QueryOptions options, boolean iterator) throws StorageEngineException { + protected Object getOrIterator(ParsedVariantQuery variantQuery, boolean iterator) throws StorageEngineException { + Query query = variantQuery.getQuery(); + QueryOptions options = variantQuery.getInputOptions(); String specificSearchIndexSamples = inferSpecificSearchIndexSamplesCollection(query, options, getMetadataManager(), dbName); if (specificSearchIndexSamples == null) { @@ -59,7 +46,7 @@ protected Object getOrIterator(Query query, QueryOptions options, boolean iterat if (iterator) { return searchManager.iterator(specificSearchIndexSamples, query, options); } else { - return searchManager.query(specificSearchIndexSamples, query, options); + return searchManager.query(specificSearchIndexSamples, variantQuery); } } catch (IOException | VariantSearchException e) { throw VariantQueryException.internalException(e); diff --git a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/search/SearchIndexVariantAggregationExecutor.java b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/search/SearchIndexVariantAggregationExecutor.java index cd466046999..eba762ab0af 100644 --- a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/search/SearchIndexVariantAggregationExecutor.java +++ b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/search/SearchIndexVariantAggregationExecutor.java @@ -4,7 +4,7 @@ import org.opencb.commons.datastore.core.FacetField; import org.opencb.commons.datastore.core.Query; import org.opencb.commons.datastore.core.QueryOptions; -import org.opencb.opencga.core.response.VariantQueryResult; +import org.opencb.opencga.storage.core.variant.query.VariantQueryResult; import org.opencb.opencga.storage.core.variant.query.executors.VariantAggregationExecutor; import org.opencb.opencga.storage.core.variant.search.solr.VariantSearchManager; import org.slf4j.Logger; diff --git a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/search/SearchIndexVariantQueryExecutor.java b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/search/SearchIndexVariantQueryExecutor.java index 137c48cd163..12c86cc4e2b 100644 --- a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/search/SearchIndexVariantQueryExecutor.java +++ b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/search/SearchIndexVariantQueryExecutor.java @@ -8,7 +8,6 @@ import org.opencb.commons.datastore.core.Query; import org.opencb.commons.datastore.core.QueryOptions; import org.opencb.opencga.core.config.storage.StorageConfiguration; -import org.opencb.opencga.core.response.VariantQueryResult; import org.opencb.opencga.storage.core.exceptions.StorageEngineException; import org.opencb.opencga.storage.core.exceptions.VariantSearchException; import org.opencb.opencga.storage.core.variant.VariantStorageEngine; @@ -16,6 +15,8 @@ import org.opencb.opencga.storage.core.variant.adaptors.VariantField; import org.opencb.opencga.storage.core.variant.adaptors.VariantQueryException; import org.opencb.opencga.storage.core.variant.adaptors.VariantQueryParam; +import org.opencb.opencga.storage.core.variant.query.ParsedVariantQuery; +import org.opencb.opencga.storage.core.variant.query.VariantQueryResult; import org.opencb.opencga.storage.core.variant.query.VariantQueryUtils; import org.opencb.opencga.storage.core.variant.search.solr.SolrNativeIterator; import org.opencb.opencga.storage.core.variant.search.solr.VariantSearchManager; @@ -80,29 +81,16 @@ public boolean canUseThisExecutor(Query query, QueryOptions options) throws Stor } @Override - public DataResult count(Query query) { - try { - StopWatch watch = StopWatch.createStarted(); - long count = searchManager.count(dbName, query); - int time = (int) watch.getTime(TimeUnit.MILLISECONDS); - return new DataResult<>(time, Collections.emptyList(), 1, Collections.singletonList(count), 1); - } catch (IOException | VariantSearchException e) { - throw new VariantQueryException("Error querying Solr", e); - } - } - - @Override - protected Object getOrIterator(Query query, QueryOptions options, boolean iterator) { - if (options == null) { - options = QueryOptions.empty(); - } + protected Object getOrIterator(ParsedVariantQuery variantQuery, boolean iterator) { + Query query = variantQuery.getQuery(); + QueryOptions options = variantQuery.getInputOptions(); if (doQuerySearchManager(query, options)) { try { if (iterator) { return searchManager.iterator(dbName, query, options); } else { - return searchManager.query(dbName, query, options); + return searchManager.query(dbName, variantQuery); } } catch (IOException | VariantSearchException e) { throw new VariantQueryException("Error querying Solr", e); @@ -134,7 +122,7 @@ protected Object getOrIterator(Query query, QueryOptions options, boolean iterat approxCount = false; } else if (options.getBoolean(APPROXIMATE_COUNT.key()) || options.getBoolean(QueryOptions.COUNT)) { options.put(QueryOptions.COUNT, false); - VariantQueryResult result = approximateCount(query, options); + VariantQueryResult result = approximateCount(variantQuery); numTotalResults = result.first(); approxCount = result.getApproximateCount(); approxCountSamplingSize = result.getApproximateCountSamplingSize(); @@ -176,7 +164,9 @@ protected Object getOrIterator(Query query, QueryOptions options, boolean iterat } } - public VariantQueryResult approximateCount(Query query, QueryOptions options) { + public VariantQueryResult approximateCount(ParsedVariantQuery variantQuery) { + Query query = variantQuery.getQuery(); + QueryOptions options = variantQuery.getInputOptions(); long count; boolean approxCount = true; int sampling = 0; @@ -193,7 +183,7 @@ public VariantQueryResult approximateCount(Query query, QueryOptions optio Query searchEngineQuery = getSearchEngineQuery(query); Query engineQuery = getEngineQuery(query, options, getMetadataManager()); - VariantQueryResult nativeResult = searchManager + DataResult nativeResult = searchManager .nativeQuery(dbName, searchEngineQuery, queryOptions); List variantIds = nativeResult.getResults().stream().map(VariantSearchModel::getId).collect(Collectors.toList()); // Adjust numSamples if the results from SearchManager is smaller than numSamples @@ -202,7 +192,7 @@ public VariantQueryResult approximateCount(Query query, QueryOptions optio approxCount = false; sampling = variantIds.size(); } - long numSearchResults = nativeResult.getNumTotalResults(); + long numSearchResults = nativeResult.getNumMatches(); long numResults; if (variantIds.isEmpty()) { @@ -223,8 +213,8 @@ public VariantQueryResult approximateCount(Query query, QueryOptions optio throw new VariantQueryException("Error querying Solr", e); } int time = (int) watch.getTime(TimeUnit.MILLISECONDS); - return new VariantQueryResult<>(time, 1, 1, Collections.emptyList(), Collections.singletonList(count), null, - SEARCH_ENGINE_ID + '+' + getStorageEngineId(), approxCount, approxCount ? sampling : null, null); + return new VariantQueryResult<>(time, 1, 1, Collections.emptyList(), Collections.singletonList(count), + SEARCH_ENGINE_ID + '+' + getStorageEngineId(), approxCount, approxCount ? sampling : null, null, variantQuery); } /** @@ -308,7 +298,7 @@ protected Iterator variantIdIteratorFromSearch(Query query, int limit, i try { // Do not iterate for small queries if (limit < 10000) { - VariantQueryResult nativeResult = searchManager.nativeQuery(dbName, query, queryOptions); + DataResult nativeResult = searchManager.nativeQuery(dbName, query, queryOptions); if (numTotalResults != null) { numTotalResults.set(nativeResult.getNumMatches()); } diff --git a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/search/solr/VariantSearchManager.java b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/search/solr/VariantSearchManager.java index 74ee51bbe3a..374f5f9ffd6 100644 --- a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/search/solr/VariantSearchManager.java +++ b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/search/solr/VariantSearchManager.java @@ -42,7 +42,8 @@ import org.opencb.commons.utils.ListUtils; import org.opencb.opencga.core.common.TimeUtils; import org.opencb.opencga.core.config.storage.StorageConfiguration; -import org.opencb.opencga.core.response.VariantQueryResult; +import org.opencb.opencga.storage.core.variant.query.ParsedVariantQuery; +import org.opencb.opencga.storage.core.variant.query.VariantQueryResult; import org.opencb.opencga.storage.core.exceptions.VariantSearchException; import org.opencb.opencga.storage.core.metadata.VariantStorageMetadataManager; import org.opencb.opencga.storage.core.utils.CellBaseUtils; @@ -278,25 +279,24 @@ public int delete(String collection, VariantDBIterator variantDBIterator, Progre * according a given query. * * @param collection Collection name - * @param query Query - * @param queryOptions Query options + * @param variantQuery Parsed variant query * @return List of Variant objects * @throws VariantSearchException VariantSearchException * @throws IOException IOException */ - public VariantQueryResult query(String collection, Query query, QueryOptions queryOptions) + public VariantQueryResult query(String collection, ParsedVariantQuery variantQuery) throws VariantSearchException, IOException { - SolrQuery solrQuery = solrQueryParser.parse(query, queryOptions); + SolrQuery solrQuery = solrQueryParser.parse(variantQuery.getQuery(), variantQuery.getInputOptions()); SolrCollection solrCollection = solrManager.getCollection(collection); DataResult queryResult; try { queryResult = solrCollection.query(solrQuery, VariantSearchModel.class, - new VariantSearchToVariantConverter(VariantField.getIncludeFields(queryOptions))); + new VariantSearchToVariantConverter(VariantField.getIncludeFields(variantQuery.getInputOptions()))); } catch (SolrServerException e) { throw new VariantSearchException("Error executing variant query", e); } - return new VariantQueryResult<>(queryResult, null, SEARCH_ENGINE_ID); + return new VariantQueryResult<>(queryResult, SEARCH_ENGINE_ID, variantQuery); } /** @@ -310,7 +310,7 @@ public VariantQueryResult query(String collection, Query query, QueryOp * @throws VariantSearchException VariantSearchException * @throws IOException IOException */ - public VariantQueryResult nativeQuery(String collection, Query query, QueryOptions queryOptions) + public DataResult nativeQuery(String collection, Query query, QueryOptions queryOptions) throws VariantSearchException, IOException { SolrQuery solrQuery = solrQueryParser.parse(query, queryOptions); SolrCollection solrCollection = solrManager.getCollection(collection); @@ -321,7 +321,7 @@ public VariantQueryResult nativeQuery(String collection, Que throw new VariantSearchException("Error executing variant query (nativeQuery)", e); } - return new VariantQueryResult<>(queryResult, null, SEARCH_ENGINE_ID); + return queryResult; } /** diff --git a/opencga-storage/opencga-storage-core/src/test/java/org/opencb/opencga/storage/core/variant/VariantStorageEngineBNDTest.java b/opencga-storage/opencga-storage-core/src/test/java/org/opencb/opencga/storage/core/variant/VariantStorageEngineBNDTest.java index 598e1fae586..08dabda7562 100644 --- a/opencga-storage/opencga-storage-core/src/test/java/org/opencb/opencga/storage/core/variant/VariantStorageEngineBNDTest.java +++ b/opencga-storage/opencga-storage-core/src/test/java/org/opencb/opencga/storage/core/variant/VariantStorageEngineBNDTest.java @@ -1,6 +1,7 @@ package org.opencb.opencga.storage.core.variant; import org.hamcrest.CoreMatchers; +import org.hamcrest.MatcherAssert; import org.junit.Before; import org.junit.Ignore; import org.junit.Test; @@ -17,6 +18,7 @@ import org.opencb.opencga.storage.core.StoragePipelineResult; import org.opencb.opencga.storage.core.exceptions.StorageEngineException; import org.opencb.opencga.storage.core.metadata.models.StudyMetadata; +import org.opencb.opencga.storage.core.variant.adaptors.VariantQuery; import org.opencb.opencga.storage.core.variant.adaptors.VariantQueryParam; import org.opencb.opencga.storage.core.variant.adaptors.iterators.VariantDBIterator; import org.opencb.opencga.storage.core.variant.io.VariantWriterFactory; @@ -75,13 +77,13 @@ public void checkAllAnnotated() throws Exception { @Test public void getPairs() throws Exception { - getPairs(new Query()); - getPairs(new Query(VariantQueryParam.REGION.key(), "2")); - getPairs(new Query(VariantQueryParam.REGION.key(), "17")); - getPairs(new Query(VariantQueryParam.REGION.key(), "2,13,5")); - getPairs(new Query(VariantQueryParam.REGION.key(), "2").append(VariantQueryParam.GENE.key(), "VPS53")); - getPairs(new Query(VariantQueryParam.GENE.key(), "VPS53")); - getPairs(new Query(VariantQueryParam.GENE.key(), "BRCA2")); + getPairs(new VariantQuery()); + getPairs(new VariantQuery().region("2")); + getPairs(new VariantQuery().region("17")); + getPairs(new VariantQuery().region("2", "13", "5")); + getPairs(new VariantQuery().region("2").gene("LINC00423")); + getPairs(new VariantQuery().gene("LINC00423")); + getPairs(new VariantQuery().gene("ENSG00000263015")); } public void getPairs(Query inputQuery) throws Exception { @@ -115,8 +117,8 @@ public void getPairs(Query inputQuery) throws Exception { } assertNull(prevMateid); assertNull(prevId); - assertThat(duplicatedVariants, CoreMatchers.not(CoreMatchers.hasItem(CoreMatchers.anything()))); - + MatcherAssert.assertThat(duplicatedVariants, CoreMatchers.not(CoreMatchers.hasItem(CoreMatchers.anything()))); + assertNotEquals(0, variants.size()); // Check pagination testPagination(variantsList, query, 1); testPagination(variantsList, query, 2); @@ -130,17 +132,19 @@ private void testPagination(List variantsList, Query query, int batchSiz List actualVariantsGet = new ArrayList<>(variantsList.size()); List actualVariantsIterator = new ArrayList<>(variantsList.size()); for (int i = 0; i < variantsList.size(); i += batchSize) { + System.out.println(" --- limit = " + batchSize + " skip = " + i); QueryOptions options = new QueryOptions(QueryOptions.LIMIT, batchSize) .append(QueryOptions.SKIP, i); - List results = variantStorageEngine.get(query, options).getResults(); - System.out.println("get = " + options.toJson() + " -> " + results.size() + " " + results); + List results; + results = variantStorageEngine.get(query, options).getResults(); + System.out.println("get = " + options.toJson() + " -> " + results.size() + " result " + results.stream().map(Variant::toString).collect(Collectors.joining("\", \"", "[ \"", "\" ]"))); results.stream().map(Variant::toString).forEach(actualVariantsGet::add); assertTrue(results.size() <= batchSize); results = new ArrayList<>(batchSize); variantStorageEngine.iterator(query, options).forEachRemaining(results::add); - System.out.println("it = " + options.toJson() + " -> " + results.size() + " " + results); - results.stream().map(Variant::toString).forEach(actualVariantsGet::add); + System.out.println("it = " + options.toJson() + " -> " + results.size() + " result " + results.stream().map(Variant::toString).collect(Collectors.joining("\", \"", "[ \"", "\" ]"))); + results.stream().map(Variant::toString).forEach(actualVariantsIterator::add); assertTrue(results.size() <= batchSize); } diff --git a/opencga-storage/opencga-storage-core/src/test/java/org/opencb/opencga/storage/core/variant/VariantStorageSearchIntersectTest.java b/opencga-storage/opencga-storage-core/src/test/java/org/opencb/opencga/storage/core/variant/VariantStorageSearchIntersectTest.java index 37c1c02b60d..3827a56da35 100644 --- a/opencga-storage/opencga-storage-core/src/test/java/org/opencb/opencga/storage/core/variant/VariantStorageSearchIntersectTest.java +++ b/opencga-storage/opencga-storage-core/src/test/java/org/opencb/opencga/storage/core/variant/VariantStorageSearchIntersectTest.java @@ -32,7 +32,7 @@ import org.opencb.commons.datastore.core.Query; import org.opencb.commons.datastore.core.QueryOptions; import org.opencb.opencga.core.api.ParamConstants; -import org.opencb.opencga.core.response.VariantQueryResult; +import org.opencb.opencga.storage.core.variant.query.VariantQueryResult; import org.opencb.opencga.storage.core.StoragePipelineResult; import org.opencb.opencga.storage.core.exceptions.StorageEngineException; import org.opencb.opencga.storage.core.metadata.VariantStorageMetadataManager; @@ -293,7 +293,7 @@ public void testCount() throws Exception { .append(ANNOT_CONSERVATION.key(), "gerp>0.1"); long realCount = dbAdaptor.count(query).first(); VariantQueryResult result = variantQueryExecutor - .get(query, new QueryOptions(COUNT, true).append(LIMIT, 0)); + .get(variantStorageEngine.parseQuery(query, new QueryOptions(COUNT, true).append(LIMIT, 0))); assertEquals(0, result.getResults().size()); assertEquals(realCount, result.getNumMatches()); } @@ -304,7 +304,7 @@ public void testApproxCount() throws Exception { .append(ANNOT_CONSERVATION.key(), "gerp>0.1"); long realCount = dbAdaptor.count(query).first(); VariantQueryResult result = variantQueryExecutor - .approximateCount(query, new QueryOptions(VariantStorageOptions.APPROXIMATE_COUNT_SAMPLING_SIZE.key(), realCount * 0.1)); + .approximateCount(variantStorageEngine.getVariantQueryParser().parseQuery(query, new QueryOptions(VariantStorageOptions.APPROXIMATE_COUNT_SAMPLING_SIZE.key(), realCount * 0.1))); long approxCount = result.first(); System.out.println("approxCount = " + approxCount); System.out.println("realCount = " + realCount); @@ -319,7 +319,7 @@ public void testExactApproxCount() throws Exception { .append(ANNOT_CONSERVATION.key(), "gerp>0.1"); long realCount = dbAdaptor.count(query).first(); VariantQueryResult result = variantQueryExecutor - .approximateCount(query, new QueryOptions(VariantStorageOptions.APPROXIMATE_COUNT_SAMPLING_SIZE.key(), allVariants.getNumResults())); + .approximateCount(variantStorageEngine.getVariantQueryParser().parseQuery(query, new QueryOptions(VariantStorageOptions.APPROXIMATE_COUNT_SAMPLING_SIZE.key(), allVariants.getNumResults()))); long approxCount = result.first(); System.out.println("approxCount = " + approxCount); System.out.println("realCount = " + realCount); @@ -333,7 +333,7 @@ public void testExactApproxCountToSearch() throws Exception { Query query = new Query(ANNOT_CONSERVATION.key(), "gerp>0.1"); long realCount = dbAdaptor.count(query).first(); VariantQueryResult result = variantQueryExecutor - .approximateCount(query, new QueryOptions(VariantStorageOptions.APPROXIMATE_COUNT_SAMPLING_SIZE.key(), allVariants.getNumResults())); + .approximateCount(variantStorageEngine.getVariantQueryParser().parseQuery(query, new QueryOptions(VariantStorageOptions.APPROXIMATE_COUNT_SAMPLING_SIZE.key(), allVariants.getNumResults()))); long approxCount = result.first(); System.out.println("approxCount = " + approxCount); System.out.println("realCount = " + realCount); diff --git a/opencga-storage/opencga-storage-core/src/test/java/org/opencb/opencga/storage/core/variant/adaptors/VariantDBAdaptorMultiFileSpecificSamplesCollectionTest.java b/opencga-storage/opencga-storage-core/src/test/java/org/opencb/opencga/storage/core/variant/adaptors/VariantDBAdaptorMultiFileSpecificSamplesCollectionTest.java index 4c267a35d15..58cc058dc4b 100644 --- a/opencga-storage/opencga-storage-core/src/test/java/org/opencb/opencga/storage/core/variant/adaptors/VariantDBAdaptorMultiFileSpecificSamplesCollectionTest.java +++ b/opencga-storage/opencga-storage-core/src/test/java/org/opencb/opencga/storage/core/variant/adaptors/VariantDBAdaptorMultiFileSpecificSamplesCollectionTest.java @@ -5,7 +5,8 @@ import org.opencb.biodata.models.variant.Variant; import org.opencb.commons.datastore.core.Query; import org.opencb.commons.datastore.core.QueryOptions; -import org.opencb.opencga.core.response.VariantQueryResult; +import org.opencb.opencga.storage.core.variant.query.ParsedVariantQuery; +import org.opencb.opencga.storage.core.variant.query.VariantQueryResult; import org.opencb.opencga.storage.core.exceptions.StorageEngineException; import org.opencb.opencga.storage.core.exceptions.VariantSearchException; import org.opencb.opencga.storage.core.metadata.VariantStorageMetadataManager; @@ -55,19 +56,19 @@ protected void load() throws Exception { protected VariantQueryResult query(Query query, QueryOptions options) { try { - query = variantStorageEngine.preProcessQuery(query, options); + ParsedVariantQuery variantQuery = variantStorageEngine.parseQuery(query, options); VariantStorageMetadataManager scm = dbAdaptor.getMetadataManager(); - String collection = VariantSearchUtils.inferSpecificSearchIndexSamplesCollection(query, options, scm, DB_NAME); + String collection = VariantSearchUtils.inferSpecificSearchIndexSamplesCollection(variantQuery.getQuery(), options, scm, DB_NAME); // Do not execute this test if the query is not covered by the specific search index collection - Assume.assumeThat(query.toJson(), collection, CoreMatchers.notNullValue()); + Assume.assumeThat(variantQuery.getQuery().toJson(), collection, CoreMatchers.notNullValue()); if (options.getInt(QueryOptions.LIMIT, 0) <= 0) { options = new QueryOptions(options); options.put(QueryOptions.LIMIT, 100000); } - return variantStorageEngine.getVariantSearchManager().query(collection, query, options); + return variantStorageEngine.getVariantSearchManager().query(collection, variantQuery); } catch (StorageEngineException | VariantSearchException | IOException e) { e.printStackTrace(); Assert.fail(e.getMessage()); diff --git a/opencga-storage/opencga-storage-core/src/test/java/org/opencb/opencga/storage/core/variant/adaptors/VariantDBAdaptorMultiFileTest.java b/opencga-storage/opencga-storage-core/src/test/java/org/opencb/opencga/storage/core/variant/adaptors/VariantDBAdaptorMultiFileTest.java index 9a95ed053e5..f52790a19c1 100644 --- a/opencga-storage/opencga-storage-core/src/test/java/org/opencb/opencga/storage/core/variant/adaptors/VariantDBAdaptorMultiFileTest.java +++ b/opencga-storage/opencga-storage-core/src/test/java/org/opencb/opencga/storage/core/variant/adaptors/VariantDBAdaptorMultiFileTest.java @@ -10,7 +10,7 @@ import org.opencb.biodata.models.variant.avro.SampleEntry; import org.opencb.biodata.models.variant.stats.VariantStats; import org.opencb.commons.datastore.core.*; -import org.opencb.opencga.core.response.VariantQueryResult; +import org.opencb.opencga.storage.core.variant.query.VariantQueryResult; import org.opencb.opencga.storage.core.exceptions.StorageEngineException; import org.opencb.opencga.storage.core.metadata.VariantStorageMetadataManager; import org.opencb.opencga.storage.core.metadata.models.FileMetadata; diff --git a/opencga-storage/opencga-storage-core/src/test/java/org/opencb/opencga/storage/core/variant/adaptors/VariantDBAdaptorTest.java b/opencga-storage/opencga-storage-core/src/test/java/org/opencb/opencga/storage/core/variant/adaptors/VariantDBAdaptorTest.java index 1f305574a64..269e2642dc5 100644 --- a/opencga-storage/opencga-storage-core/src/test/java/org/opencb/opencga/storage/core/variant/adaptors/VariantDBAdaptorTest.java +++ b/opencga-storage/opencga-storage-core/src/test/java/org/opencb/opencga/storage/core/variant/adaptors/VariantDBAdaptorTest.java @@ -30,14 +30,11 @@ import org.opencb.biodata.models.variant.Variant; import org.opencb.biodata.models.variant.VariantFileMetadata; import org.opencb.biodata.models.variant.avro.*; -import org.opencb.biodata.models.variant.exceptions.NonStandardCompliantSampleField; import org.opencb.biodata.models.variant.stats.VariantStats; -import org.opencb.biodata.tools.variant.VariantNormalizer; import org.opencb.commons.datastore.core.DataResult; import org.opencb.commons.datastore.core.ObjectMap; import org.opencb.commons.datastore.core.Query; import org.opencb.commons.datastore.core.QueryOptions; -import org.opencb.opencga.core.response.VariantQueryResult; import org.opencb.opencga.storage.core.StoragePipelineResult; import org.opencb.opencga.storage.core.exceptions.StorageEngineException; import org.opencb.opencga.storage.core.metadata.VariantStorageMetadataManager; @@ -47,6 +44,8 @@ import org.opencb.opencga.storage.core.variant.VariantStorageOptions; import org.opencb.opencga.storage.core.variant.adaptors.iterators.VariantDBIterator; import org.opencb.opencga.storage.core.variant.annotation.annotators.CellBaseRestVariantAnnotator; +import org.opencb.opencga.storage.core.variant.query.ParsedVariantQuery; +import org.opencb.opencga.storage.core.variant.query.VariantQueryResult; import org.opencb.opencga.storage.core.variant.query.VariantQueryUtils; import org.opencb.opencga.storage.core.variant.query.executors.NoOpVariantQueryExecutor; import org.opencb.opencga.storage.core.variant.query.filters.VariantFilterBuilder; @@ -268,8 +267,8 @@ public void multiIterator() throws Exception { VariantDBIterator iterator = dbAdaptor.iterator(variantsToQuery.iterator(), new Query(), new QueryOptions()); - DataResult queryResult = iterator.toDataResult(); - assertEquals(variantsToQuery.size(), queryResult.getResults().size()); + List variants = iterator.toList(); + assertEquals(variantsToQuery.size(), variants.size()); } @Test @@ -2420,7 +2419,8 @@ private void testQuery(Query query, QueryOptions options) { } private Matcher withFilter(Query query) { - return VariantMatchers.withFilter(new VariantFilterBuilder(metadataManager).buildFilter(query, null), query.toJson()); + ParsedVariantQuery parsedVariantQuery = variantStorageEngine.parseQuery(query, new QueryOptions()); + return VariantMatchers.withFilter(new VariantFilterBuilder().buildFilter(parsedVariantQuery), query.toJson()); } /* @Test diff --git a/opencga-storage/opencga-storage-core/src/test/java/org/opencb/opencga/storage/core/variant/adaptors/VariantQueryUsingSearchIndexTest.java b/opencga-storage/opencga-storage-core/src/test/java/org/opencb/opencga/storage/core/variant/adaptors/VariantQueryUsingSearchIndexTest.java index 395e41d2675..6194d25c6d8 100644 --- a/opencga-storage/opencga-storage-core/src/test/java/org/opencb/opencga/storage/core/variant/adaptors/VariantQueryUsingSearchIndexTest.java +++ b/opencga-storage/opencga-storage-core/src/test/java/org/opencb/opencga/storage/core/variant/adaptors/VariantQueryUsingSearchIndexTest.java @@ -6,7 +6,7 @@ import org.opencb.commons.datastore.core.DataResult; import org.opencb.commons.datastore.core.Query; import org.opencb.commons.datastore.core.QueryOptions; -import org.opencb.opencga.core.response.VariantQueryResult; +import org.opencb.opencga.storage.core.variant.query.VariantQueryResult; import org.opencb.opencga.storage.core.variant.VariantStorageEngine; import org.opencb.opencga.storage.core.variant.adaptors.iterators.VariantDBIterator; import org.opencb.opencga.storage.core.variant.search.solr.VariantSearchManager; diff --git a/opencga-storage/opencga-storage-core/src/test/java/org/opencb/opencga/storage/core/variant/dummy/DummyVariantDBAdaptor.java b/opencga-storage/opencga-storage-core/src/test/java/org/opencb/opencga/storage/core/variant/dummy/DummyVariantDBAdaptor.java index 71fa34998de..b77ea4e08bc 100644 --- a/opencga-storage/opencga-storage-core/src/test/java/org/opencb/opencga/storage/core/variant/dummy/DummyVariantDBAdaptor.java +++ b/opencga-storage/opencga-storage-core/src/test/java/org/opencb/opencga/storage/core/variant/dummy/DummyVariantDBAdaptor.java @@ -28,7 +28,7 @@ import org.opencb.commons.datastore.core.DataResult; import org.opencb.commons.datastore.core.Query; import org.opencb.commons.datastore.core.QueryOptions; -import org.opencb.opencga.core.response.VariantQueryResult; +import org.opencb.opencga.storage.core.variant.query.VariantQueryResult; import org.opencb.opencga.storage.core.metadata.VariantStorageMetadataManager; import org.opencb.opencga.storage.core.metadata.models.CohortMetadata; import org.opencb.opencga.storage.core.metadata.models.StudyMetadata; @@ -72,13 +72,13 @@ public DummyVariantDBAdaptor(String dbName) { } @Override - public VariantQueryResult get(ParsedVariantQuery query, QueryOptions options) { + public VariantQueryResult get(ParsedVariantQuery query) { List variants = new ArrayList<>(); - iterator(query, options).forEachRemaining(variants::add); + iterator(query).forEachRemaining(variants::add); - return new VariantQueryResult<>(0, variants.size(), variants.size(), Collections.emptyList(), variants, null, - DummyVariantStorageEngine.STORAGE_ENGINE_ID); + return new VariantQueryResult<>(0, variants.size(), variants.size(), Collections.emptyList(), variants, + DummyVariantStorageEngine.STORAGE_ENGINE_ID, query); } @Override @@ -102,7 +102,8 @@ public DataResult distinct(Query query, String field) { } @Override - public VariantDBIterator iterator(ParsedVariantQuery variantQuery, QueryOptions options) { + public VariantDBIterator iterator(ParsedVariantQuery variantQuery) { + QueryOptions options = variantQuery.getInputOptions(); logger.info("Query " + variantQuery.getQuery().toJson()); logger.info("QueryOptions " + options.toJson()); logger.info("dbName " + dbName); diff --git a/opencga-storage/opencga-storage-core/src/test/java/org/opencb/opencga/storage/core/variant/query/VariantQueryParserTest.java b/opencga-storage/opencga-storage-core/src/test/java/org/opencb/opencga/storage/core/variant/query/VariantQueryParserTest.java index 8fae5f12310..2611cfc337a 100644 --- a/opencga-storage/opencga-storage-core/src/test/java/org/opencb/opencga/storage/core/variant/query/VariantQueryParserTest.java +++ b/opencga-storage/opencga-storage-core/src/test/java/org/opencb/opencga/storage/core/variant/query/VariantQueryParserTest.java @@ -101,10 +101,17 @@ public static Set set(T... ts) { @Test public void testParseClinicalCombinations() { - assertEquals(Arrays.asList("cosmic"), VariantQueryParser.parseClinicalCombinationsList(new Query(ANNOT_CLINICAL.key(), "cosmic"))); - assertEquals(Arrays.asList("clinvar", "cosmic"), VariantQueryParser.parseClinicalCombinationsList(new Query(ANNOT_CLINICAL.key(), "clinvar,cosmic"))); - assertEquals(Arrays.asList("cosmic_pathogenic"), VariantQueryParser.parseClinicalCombinationsList(new Query(ANNOT_CLINICAL.key(), "cosmic").append(ANNOT_CLINICAL_SIGNIFICANCE.key(), "pathogenic"))); - assertEquals(Arrays.asList("cosmic_confirmed"), VariantQueryParser.parseClinicalCombinationsList(new Query(ANNOT_CLINICAL.key(), "cosmic").append(ANNOT_CLINICAL_CONFIRMED_STATUS.key(), true))); - assertEquals(Arrays.asList("clinvar_pathogenic_confirmed", "clinvar_likely_pathogenic_confirmed", "cosmic_pathogenic_confirmed", "cosmic_likely_pathogenic_confirmed"), VariantQueryParser.parseClinicalCombinationsList(new Query(ANNOT_CLINICAL.key(), "clinvar,cosmic").append(ANNOT_CLINICAL_SIGNIFICANCE.key(), "pathogenic,likely_pathogenic").append(ANNOT_CLINICAL_CONFIRMED_STATUS.key(), true))); + assertEquals(Arrays.asList("cosmic"), variantQueryParser.parseQuery( + new Query(ANNOT_CLINICAL.key(), "cosmic"), new QueryOptions()).getClinicalCombinationsList()); + assertEquals(Arrays.asList("clinvar", "cosmic"), variantQueryParser.parseQuery( + new Query(ANNOT_CLINICAL.key(), "clinvar,cosmic"), new QueryOptions()).getClinicalCombinationsList()); + assertEquals(Arrays.asList("cosmic_pathogenic"), variantQueryParser.parseQuery( + new Query(ANNOT_CLINICAL.key(), "cosmic").append(ANNOT_CLINICAL_SIGNIFICANCE.key(), "pathogenic"), new QueryOptions()).getClinicalCombinationsList()); + assertEquals(Arrays.asList("cosmic_confirmed"), variantQueryParser.parseQuery( + new Query(ANNOT_CLINICAL.key(), "cosmic").append(ANNOT_CLINICAL_CONFIRMED_STATUS.key(), true), new QueryOptions()).getClinicalCombinationsList()); + assertEquals(Arrays.asList("clinvar_pathogenic_confirmed", "clinvar_likely_pathogenic_confirmed", "cosmic_pathogenic_confirmed", "cosmic_likely_pathogenic_confirmed"), variantQueryParser.parseQuery(new Query() + .append(ANNOT_CLINICAL.key(), "clinvar,cosmic") + .append(ANNOT_CLINICAL_SIGNIFICANCE.key(), "pathogenic,likely_pathogenic") + .append(ANNOT_CLINICAL_CONFIRMED_STATUS.key(), true), new QueryOptions()).getClinicalCombinationsList()); } } \ No newline at end of file diff --git a/opencga-storage/opencga-storage-core/src/test/java/org/opencb/opencga/storage/core/variant/search/SearchIndexSamplesTest.java b/opencga-storage/opencga-storage-core/src/test/java/org/opencb/opencga/storage/core/variant/search/SearchIndexSamplesTest.java index bd25023f6dc..12cb35f8714 100644 --- a/opencga-storage/opencga-storage-core/src/test/java/org/opencb/opencga/storage/core/variant/search/SearchIndexSamplesTest.java +++ b/opencga-storage/opencga-storage-core/src/test/java/org/opencb/opencga/storage/core/variant/search/SearchIndexSamplesTest.java @@ -229,7 +229,8 @@ protected void checkLoadedData(String collection, List samples) Query query = new Query(SAMPLE.key(), samples); int expectedCount = variantStorageEngine.getDBAdaptor().count(query).first().intValue(); - assertEquals(expectedCount, variantSearchManager.query(collection, new Query(), new QueryOptions()).getNumTotalResults()); + assertEquals(expectedCount, variantSearchManager.query(collection, variantStorageEngine.parseQuery(new Query(), new QueryOptions())) + .getNumTotalResults()); SolrVariantDBIterator solrIterator = variantSearchManager.iterator(collection, new Query(), new QueryOptions(QueryOptions.SORT, true)); diff --git a/opencga-storage/opencga-storage-core/src/test/java/org/opencb/opencga/storage/core/variant/search/VariantSearchIndexTest.java b/opencga-storage/opencga-storage-core/src/test/java/org/opencb/opencga/storage/core/variant/search/VariantSearchIndexTest.java index b83d1a9338e..4d5d8da6716 100644 --- a/opencga-storage/opencga-storage-core/src/test/java/org/opencb/opencga/storage/core/variant/search/VariantSearchIndexTest.java +++ b/opencga-storage/opencga-storage-core/src/test/java/org/opencb/opencga/storage/core/variant/search/VariantSearchIndexTest.java @@ -215,7 +215,7 @@ public void checkVariantSearchIndex(VariantDBAdaptor dbAdaptor) throws IOExcepti TreeSet variantsFromSearch = new TreeSet<>(Comparator.comparing(Variant::toString)); TreeSet variantsFromDB = new TreeSet<>(Comparator.comparing(Variant::toString)); - variantsFromSearch.addAll(variantStorageEngine.getVariantSearchManager().query(DB_NAME, query, queryOptions).getResults()); + variantsFromSearch.addAll(variantStorageEngine.getVariantSearchManager().query(DB_NAME, variantStorageEngine.parseQuery(query, queryOptions)).getResults()); variantsFromDB.addAll(dbAdaptor.get(query, queryOptions).getResults()); assertEquals(variantsFromDB.size(), variantsFromSearch.size()); diff --git a/opencga-storage/opencga-storage-core/src/test/java/org/opencb/opencga/storage/core/variant/search/VariantSearchTest.java b/opencga-storage/opencga-storage-core/src/test/java/org/opencb/opencga/storage/core/variant/search/VariantSearchTest.java index a8fe6d9790a..56588d25863 100644 --- a/opencga-storage/opencga-storage-core/src/test/java/org/opencb/opencga/storage/core/variant/search/VariantSearchTest.java +++ b/opencga-storage/opencga-storage-core/src/test/java/org/opencb/opencga/storage/core/variant/search/VariantSearchTest.java @@ -21,7 +21,7 @@ import org.opencb.commons.datastore.solr.FacetQueryParser; import org.opencb.commons.utils.ListUtils; import org.opencb.opencga.core.common.JacksonUtils; -import org.opencb.opencga.core.response.VariantQueryResult; +import org.opencb.opencga.storage.core.variant.query.VariantQueryResult; import org.opencb.opencga.core.testclassification.duration.MediumTests; import org.opencb.opencga.storage.core.metadata.VariantStorageMetadataManager; import org.opencb.opencga.storage.core.metadata.models.StudyMetadata; @@ -67,8 +67,8 @@ public void testTranscriptInfo() throws Exception { variantSearchManager.insert(collection, annotatedVariants); - VariantQueryResult results = variantSearchManager.query(collection, new Query(), - new QueryOptions(QueryOptions.LIMIT, limit)); + VariantQueryResult results = variantSearchManager.query(collection, variantStorageEngine.parseQuery(new Query(), + new QueryOptions(QueryOptions.LIMIT, limit))); for (int i = 0; i < limit; i++) { Variant expectedVariant = annotatedVariants.get(i); @@ -213,8 +213,8 @@ public void testSpecialCharacter() throws Exception { query.put(VariantQueryParam.FILE.key(), fileId); query.put(VariantQueryParam.FILTER.key(), "PASS"); query.put(VariantQueryParam.ANNOT_CLINICAL_SIGNIFICANCE.key(), "benign"); - VariantQueryResult results = variantSearchManager.query(collection, query, - new QueryOptions(QueryOptions.LIMIT, limit)); + VariantQueryResult results = variantSearchManager.query(collection, variantStorageEngine.parseQuery(query, + new QueryOptions(QueryOptions.LIMIT, limit))); if (results.getResults().size() > 0) { System.out.println(results.getResults().get(0).toJson()); diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/HadoopVariantQueryParser.java b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/HadoopVariantQueryParser.java new file mode 100644 index 00000000000..45682df31f4 --- /dev/null +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/HadoopVariantQueryParser.java @@ -0,0 +1,36 @@ +package org.opencb.opencga.storage.hadoop.variant; + +import org.opencb.commons.datastore.core.Query; +import org.opencb.commons.datastore.core.QueryOptions; +import org.opencb.opencga.storage.core.metadata.VariantStorageMetadataManager; +import org.opencb.opencga.storage.core.utils.CellBaseUtils; +import org.opencb.opencga.storage.core.variant.query.VariantQueryParser; + +import java.util.List; + +import static org.opencb.opencga.storage.core.variant.adaptors.VariantQueryParam.STUDY; +import static org.opencb.opencga.storage.core.variant.query.VariantQueryUtils.*; + +public class HadoopVariantQueryParser extends VariantQueryParser { + public HadoopVariantQueryParser(CellBaseUtils cellBaseUtils, VariantStorageMetadataManager metadataManager) { + super(cellBaseUtils, metadataManager); + } + + @Override + public Query preProcessQuery(Query originalQuery, QueryOptions options) { + Query query = super.preProcessQuery(originalQuery, options); + List studyNames = metadataManager.getStudyNames(); + + if (isValidParam(query, STUDY) && studyNames.size() == 1) { + String study = query.getString(STUDY.key()); + if (!isNegated(study)) { + // Check that study exists + metadataManager.getStudyId(study); + query.remove(STUDY.key()); + } + } + + convertGenesToRegionsQuery(query, cellBaseUtils); + return query; + } +} diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/HadoopVariantStorageEngine.java b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/HadoopVariantStorageEngine.java index 917b679cf1c..8052ac5622c 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/HadoopVariantStorageEngine.java +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/HadoopVariantStorageEngine.java @@ -47,7 +47,6 @@ import org.opencb.opencga.storage.core.metadata.VariantMetadataFactory; import org.opencb.opencga.storage.core.metadata.VariantStorageMetadataManager; import org.opencb.opencga.storage.core.metadata.models.*; -import org.opencb.opencga.storage.core.utils.CellBaseUtils; import org.opencb.opencga.storage.core.variant.VariantStorageEngine; import org.opencb.opencga.storage.core.variant.VariantStorageOptions; import org.opencb.opencga.storage.core.variant.VariantStoragePipeline; @@ -59,6 +58,7 @@ import org.opencb.opencga.storage.core.variant.annotation.annotators.VariantAnnotator; import org.opencb.opencga.storage.core.variant.io.VariantExporter; import org.opencb.opencga.storage.core.variant.query.ParsedVariantQuery; +import org.opencb.opencga.storage.core.variant.query.VariantQueryParser; import org.opencb.opencga.storage.core.variant.query.executors.*; import org.opencb.opencga.storage.core.variant.score.VariantScoreFormatDescriptor; import org.opencb.opencga.storage.core.variant.search.SamplesSearchIndexVariantQueryExecutor; @@ -115,8 +115,6 @@ import static org.opencb.opencga.storage.core.variant.VariantStorageOptions.*; import static org.opencb.opencga.storage.core.variant.adaptors.VariantQueryParam.REGION; -import static org.opencb.opencga.storage.core.variant.adaptors.VariantQueryParam.STUDY; -import static org.opencb.opencga.storage.core.variant.query.VariantQueryUtils.*; import static org.opencb.opencga.storage.hadoop.variant.HadoopVariantStorageOptions.*; import static org.opencb.opencga.storage.hadoop.variant.gaps.FillGapsDriver.*; @@ -1041,36 +1039,41 @@ public ParsedVariantQuery parseQuery(Query originalQuery, QueryOptions options) } @Override - public Query preProcessQuery(Query originalQuery, QueryOptions options) { - Query query = super.preProcessQuery(originalQuery, options); - - VariantStorageMetadataManager metadataManager; - CellBaseUtils cellBaseUtils; - try { - metadataManager = getMetadataManager(); - cellBaseUtils = getCellBaseUtils(); - } catch (StorageEngineException e) { - throw VariantQueryException.internalException(e); - } - List studyNames = metadataManager.getStudyNames(); - - if (isValidParam(query, STUDY) && studyNames.size() == 1) { - String study = query.getString(STUDY.key()); - if (!isNegated(study)) { - try { - // Check that study exists - getMetadataManager().getStudyId(study); - } catch (StorageEngineException e) { - throw VariantQueryException.internalException(e); - } - query.remove(STUDY.key()); - } - } - - convertGenesToRegionsQuery(query, cellBaseUtils); - return query; + protected VariantQueryParser getVariantQueryParser() throws StorageEngineException { + return new HadoopVariantQueryParser(getCellBaseUtils(), getMetadataManager()); } +// @Override +// public Query preProcessQuery(Query originalQuery, QueryOptions options) { +// Query query = super.preProcessQuery(originalQuery, options); +// +// VariantStorageMetadataManager metadataManager; +// CellBaseUtils cellBaseUtils; +// try { +// metadataManager = getMetadataManager(); +// cellBaseUtils = getCellBaseUtils(); +// } catch (StorageEngineException e) { +// throw VariantQueryException.internalException(e); +// } +// List studyNames = metadataManager.getStudyNames(); +// +// if (isValidParam(query, STUDY) && studyNames.size() == 1) { +// String study = query.getString(STUDY.key()); +// if (!isNegated(study)) { +// try { +// // Check that study exists +// getMetadataManager().getStudyId(study); +// } catch (StorageEngineException e) { +// throw VariantQueryException.internalException(e); +// } +// query.remove(STUDY.key()); +// } +// } +// +// convertGenesToRegionsQuery(query, cellBaseUtils); +// return query; +// } + @Override protected List initVariantAggregationExecutors() { List executors = new ArrayList<>(3); @@ -1177,7 +1180,7 @@ protected List initVariantQueryExecutors() throws StorageE executors.add(new SampleIndexCompoundHeterozygousQueryExecutor( getMetadataManager(), getStorageEngineId(), getOptions(), this, getSampleIndexDBAdaptor(), getDBAdaptor())); executors.add(new BreakendVariantQueryExecutor( - getMetadataManager(), getStorageEngineId(), getOptions(), new SampleIndexVariantQueryExecutor( + getStorageEngineId(), getOptions(), new SampleIndexVariantQueryExecutor( getDBAdaptor(), getSampleIndexDBAdaptor(), getStorageEngineId(), getOptions()), getDBAdaptor())); executors.add(new SamplesSearchIndexVariantQueryExecutor( getDBAdaptor(), getVariantSearchManager(), getStorageEngineId(), dbName, getConfiguration(), getOptions())); diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/adaptors/HBaseColumnIntersectVariantQueryExecutor.java b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/adaptors/HBaseColumnIntersectVariantQueryExecutor.java index 40d45a70bee..c672e94fb58 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/adaptors/HBaseColumnIntersectVariantQueryExecutor.java +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/adaptors/HBaseColumnIntersectVariantQueryExecutor.java @@ -2,14 +2,14 @@ import com.google.common.collect.Iterators; import org.opencb.biodata.models.variant.Variant; -import org.opencb.commons.datastore.core.DataResult; import org.opencb.commons.datastore.core.ObjectMap; import org.opencb.commons.datastore.core.Query; import org.opencb.commons.datastore.core.QueryOptions; -import org.opencb.opencga.core.response.VariantQueryResult; import org.opencb.opencga.storage.core.variant.VariantStorageOptions; import org.opencb.opencga.storage.core.variant.adaptors.VariantDBAdaptor; import org.opencb.opencga.storage.core.variant.query.ParsedQuery; +import org.opencb.opencga.storage.core.variant.query.ParsedVariantQuery; +import org.opencb.opencga.storage.core.variant.query.VariantQueryResult; import org.opencb.opencga.storage.core.variant.query.VariantQueryUtils; import org.opencb.opencga.storage.core.variant.query.executors.VariantQueryExecutor; import org.slf4j.Logger; @@ -76,23 +76,19 @@ public boolean canUseThisExecutor(Query query, QueryOptions options) { return false; } - @Override - public DataResult count(Query query) { - throw new UnsupportedOperationException("Count not implemented in " + getClass()); - } - /** * Intersect result of column hbase scan and full phoenix query. * Use {@link org.opencb.opencga.storage.core.variant.adaptors.iterators.MultiVariantDBIterator}. * - * @param query Query - * @param options Options + * @param variantQuery Parsed query * @param iterator Shall the resulting object be an iterator instead of a DataResult * @return DataResult or Iterator with the variants that matches the query */ @Override - protected Object getOrIterator(Query query, QueryOptions options, boolean iterator) { + protected Object getOrIterator(ParsedVariantQuery variantQuery, boolean iterator) { logger.info("HBase column intersect"); + Query query = variantQuery.getQuery(); + QueryOptions options = variantQuery.getInputOptions(); // Build the query with only one query filter -> Single HBase column filter // diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/adaptors/VariantHadoopDBAdaptor.java b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/adaptors/VariantHadoopDBAdaptor.java index 3d6fe440da1..38b4d9c1718 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/adaptors/VariantHadoopDBAdaptor.java +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/adaptors/VariantHadoopDBAdaptor.java @@ -33,7 +33,6 @@ import org.opencb.commons.datastore.core.Query; import org.opencb.commons.datastore.core.*; import org.opencb.opencga.core.config.storage.StorageConfiguration; -import org.opencb.opencga.core.response.VariantQueryResult; import org.opencb.opencga.storage.core.exceptions.StorageEngineException; import org.opencb.opencga.storage.core.metadata.VariantStorageMetadataManager; import org.opencb.opencga.storage.core.metadata.models.ProjectMetadata; @@ -45,6 +44,7 @@ import org.opencb.opencga.storage.core.variant.annotation.VariantAnnotationManager; import org.opencb.opencga.storage.core.variant.query.ParsedVariantQuery; import org.opencb.opencga.storage.core.variant.query.VariantQueryParser; +import org.opencb.opencga.storage.core.variant.query.VariantQueryResult; import org.opencb.opencga.storage.core.variant.query.VariantQueryUtils; import org.opencb.opencga.storage.core.variant.query.projection.VariantQueryProjection; import org.opencb.opencga.storage.core.variant.query.projection.VariantQueryProjectionParser; @@ -52,6 +52,7 @@ import org.opencb.opencga.storage.hadoop.auth.HBaseCredentials; import org.opencb.opencga.storage.hadoop.utils.HBaseManager; import org.opencb.opencga.storage.hadoop.variant.GenomeHelper; +import org.opencb.opencga.storage.hadoop.variant.HadoopVariantQueryParser; import org.opencb.opencga.storage.hadoop.variant.HadoopVariantStorageEngine; import org.opencb.opencga.storage.hadoop.variant.HadoopVariantStorageOptions; import org.opencb.opencga.storage.hadoop.variant.adaptors.iterators.VariantHBaseResultSetIterator; @@ -221,33 +222,29 @@ public void close() throws IOException { } @Override - public VariantQueryResult get(ParsedVariantQuery query, QueryOptions options) { + public VariantQueryResult get(ParsedVariantQuery query) { List variants = new LinkedList<>(); - VariantDBIterator iterator = iterator(query, options); + VariantDBIterator iterator = iterator(query); + QueryOptions options = new QueryOptions(query.getInputOptions()); iterator.forEachRemaining(variants::add); long numTotalResults; - if (options == null) { - numTotalResults = variants.size(); - } else { - if (options.getInt(QueryOptions.LIMIT, -1) >= 0) { - if (options.getBoolean(QueryOptions.COUNT, false)) { - numTotalResults = count(query).first(); - } else { - numTotalResults = -1; - } + if (options.getInt(QueryOptions.LIMIT, -1) >= 0) { + if (options.getBoolean(QueryOptions.COUNT, false)) { + numTotalResults = count(query).first(); } else { - // There are no limit. Do not count. - numTotalResults = variants.size(); + numTotalResults = -1; } + } else { + // There are no limit. Do not count. + numTotalResults = variants.size(); } - VariantQueryResult result = new VariantQueryResult<>(iterator.getTime(TimeUnit.MILLISECONDS), variants.size(), - numTotalResults, null, variants, null, HadoopVariantStorageEngine.STORAGE_ENGINE_ID) + return new VariantQueryResult<>(iterator.getTime(TimeUnit.MILLISECONDS), variants.size(), + numTotalResults, null, variants, HadoopVariantStorageEngine.STORAGE_ENGINE_ID, query) .setFetchTime(iterator.getTimeFetching(TimeUnit.MILLISECONDS)) .setConvertTime(iterator.getTimeConverting(TimeUnit.MILLISECONDS)); - return addSamplesMetadataIfRequested(result, query.getQuery(), options, getMetadataManager()); } @Override @@ -334,7 +331,8 @@ public DataResult distinct(Query query, String field) { } @Override - public VariantDBIterator iterator(ParsedVariantQuery variantQuery, QueryOptions options) { + public VariantDBIterator iterator(ParsedVariantQuery variantQuery) { + QueryOptions options = variantQuery.getInputOptions(); if (options == null) { options = new QueryOptions(); } else { @@ -385,7 +383,7 @@ public VariantDBIterator iterator(ParsedVariantQuery variantQuery, QueryOptions private VariantHBaseResultSetIterator phoenixIterator(ParsedVariantQuery variantQuery, QueryOptions options, HBaseVariantConverterConfiguration converterConfiguration) { VariantStorageMetadataManager metadataManager = getMetadataManager(); - new VariantQueryParser(null, metadataManager).optimize(variantQuery); + new HadoopVariantQueryParser(null, metadataManager).optimize(variantQuery); logger.debug("Table name = " + variantTable); logger.info("Query : " + VariantQueryUtils.printQuery(variantQuery.getQuery())); @@ -679,7 +677,7 @@ private class VariantQueryIteratorCustomSplit extends MultiVariantDBIterator.Var VariantQueryIteratorCustomSplit(Iterator variants, Query query, int batchSize, QueryOptions options) { super(variants, query, batchSize); - parser = new VariantQueryParser(null, getMetadataManager()); + parser = new HadoopVariantQueryParser(null, getMetadataManager()); variantQuery = parser.parseQuery(query, options); cts = sizeOrOne(variantQuery.getConsequenceTypes()); bts = sizeOrOne(variantQuery.getBiotypes()); diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/adaptors/phoenix/VariantSqlQueryParser.java b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/adaptors/phoenix/VariantSqlQueryParser.java index bb9737144d2..2d5c66b6dd9 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/adaptors/phoenix/VariantSqlQueryParser.java +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/adaptors/phoenix/VariantSqlQueryParser.java @@ -44,6 +44,7 @@ import org.opencb.opencga.storage.core.variant.query.*; import org.opencb.opencga.storage.core.variant.query.projection.VariantQueryProjection; import org.opencb.opencga.storage.core.variant.query.projection.VariantQueryProjectionParser; +import org.opencb.opencga.storage.hadoop.variant.HadoopVariantQueryParser; import org.opencb.opencga.storage.hadoop.variant.converters.HBaseToVariantConverter; import org.opencb.opencga.storage.hadoop.variant.converters.annotation.VariantAnnotationToPhoenixConverter; import org.opencb.opencga.storage.hadoop.variant.converters.study.HBaseToStudyEntryConverter; @@ -116,7 +117,7 @@ public VariantSqlQueryParser(String variantTable, @Deprecated public String parse(Query query, QueryOptions options) { - VariantQueryParser parser = new VariantQueryParser(null, metadataManager); + VariantQueryParser parser = new HadoopVariantQueryParser(null, metadataManager); ParsedVariantQuery variantQuery = parser.parseQuery(query, options, true); return parse(variantQuery, options); } diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/index/SampleIndexCompoundHeterozygousQueryExecutor.java b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/index/SampleIndexCompoundHeterozygousQueryExecutor.java index cb2019c2f6d..c7599e7e288 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/index/SampleIndexCompoundHeterozygousQueryExecutor.java +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/index/SampleIndexCompoundHeterozygousQueryExecutor.java @@ -5,7 +5,7 @@ import org.opencb.commons.datastore.core.ObjectMap; import org.opencb.commons.datastore.core.Query; import org.opencb.commons.datastore.core.QueryOptions; -import org.opencb.opencga.core.response.VariantQueryResult; +import org.opencb.opencga.storage.core.variant.query.VariantQueryResult; import org.opencb.opencga.storage.core.metadata.VariantStorageMetadataManager; import org.opencb.opencga.storage.core.metadata.models.Trio; import org.opencb.opencga.storage.core.variant.VariantStorageOptions; diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/index/SampleIndexMendelianErrorQueryExecutor.java b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/index/SampleIndexMendelianErrorQueryExecutor.java index 68eed2db889..4dd50c9eacf 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/index/SampleIndexMendelianErrorQueryExecutor.java +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/index/SampleIndexMendelianErrorQueryExecutor.java @@ -15,6 +15,7 @@ import org.opencb.opencga.storage.core.metadata.models.Trio; import org.opencb.opencga.storage.core.variant.adaptors.GenotypeClass; import org.opencb.opencga.storage.core.variant.adaptors.iterators.VariantDBIterator; +import org.opencb.opencga.storage.core.variant.query.ParsedVariantQuery; import org.opencb.opencga.storage.core.variant.query.VariantQueryUtils; import org.opencb.opencga.storage.hadoop.variant.adaptors.VariantHadoopDBAdaptor; import org.opencb.opencga.storage.hadoop.variant.index.query.SampleIndexQuery; @@ -43,7 +44,7 @@ public boolean canUseThisExecutor(Query query, QueryOptions options) { } @Override - protected Object getOrIterator(Query query, QueryOptions options, boolean iterator, SampleIndexQuery sampleIndexQuery) { + protected Object getOrIterator(ParsedVariantQuery variantQuery, boolean iterator, SampleIndexQuery sampleIndexQuery) { List trios = new ArrayList<>(sampleIndexQuery.getMendelianErrorSet().size()); int studyId = metadataManager.getStudyId(sampleIndexQuery.getStudy()); @@ -65,7 +66,7 @@ protected Object getOrIterator(Query query, QueryOptions options, boolean iterat trios.add(new Trio(null, father, mother, sampleMetadata.getName())); } - Object object = super.getOrIterator(query, options, iterator, sampleIndexQuery); + Object object = super.getOrIterator(variantQuery, iterator, sampleIndexQuery); if (iterator) { VariantDBIterator variantIterator = (VariantDBIterator) object; diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/index/SampleIndexOnlyVariantQueryExecutor.java b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/index/SampleIndexOnlyVariantQueryExecutor.java index 510085420dd..371d57ac4da 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/index/SampleIndexOnlyVariantQueryExecutor.java +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/index/SampleIndexOnlyVariantQueryExecutor.java @@ -9,7 +9,6 @@ import org.opencb.biodata.models.variant.avro.FileEntry; import org.opencb.biodata.models.variant.avro.SampleEntry; import org.opencb.biodata.tools.commons.Converter; -import org.opencb.commons.datastore.core.DataResult; import org.opencb.commons.datastore.core.ObjectMap; import org.opencb.commons.datastore.core.Query; import org.opencb.commons.datastore.core.QueryOptions; @@ -17,7 +16,6 @@ import org.opencb.opencga.core.common.BatchUtils; import org.opencb.opencga.core.common.TimeUtils; import org.opencb.opencga.core.config.storage.IndexFieldConfiguration; -import org.opencb.opencga.core.response.VariantQueryResult; import org.opencb.opencga.storage.core.io.bit.BitBuffer; import org.opencb.opencga.storage.core.metadata.VariantStorageMetadataManager; import org.opencb.opencga.storage.core.metadata.models.SampleMetadata; @@ -26,7 +24,7 @@ import org.opencb.opencga.storage.core.variant.adaptors.*; import org.opencb.opencga.storage.core.variant.adaptors.iterators.VariantDBIterator; import org.opencb.opencga.storage.core.variant.query.ParsedVariantQuery; -import org.opencb.opencga.storage.core.variant.query.VariantQueryParser; +import org.opencb.opencga.storage.core.variant.query.VariantQueryResult; import org.opencb.opencga.storage.core.variant.query.VariantQueryUtils; import org.opencb.opencga.storage.core.variant.query.executors.VariantQueryExecutor; import org.opencb.opencga.storage.core.variant.query.projection.VariantQueryProjection; @@ -50,7 +48,6 @@ import java.util.stream.Collectors; import static org.opencb.opencga.storage.core.variant.query.VariantQueryUtils.NONE; -import static org.opencb.opencga.storage.core.variant.query.VariantQueryUtils.addSamplesMetadataIfRequested; import static org.opencb.opencga.storage.hadoop.variant.HadoopVariantStorageOptions.SAMPLE_INDEX_QUERY_SAMPLE_INDEX_ONLY_PD_BATCH; import static org.opencb.opencga.storage.hadoop.variant.HadoopVariantStorageOptions.SAMPLE_INDEX_QUERY_SAMPLE_INDEX_ONLY_PD_BUFFER; import static org.opencb.opencga.storage.hadoop.variant.index.SampleIndexVariantQueryExecutor.SAMPLE_INDEX_TABLE_SOURCE; @@ -64,7 +61,6 @@ public class SampleIndexOnlyVariantQueryExecutor extends VariantQueryExecutor { private final SampleIndexDBAdaptor sampleIndexDBAdaptor; private final VariantHadoopDBAdaptor dbAdaptor; - private final VariantQueryParser variantQueryParser; private final VariantQueryProjectionParser variantQueryProjectionParser; private static Logger logger = LoggerFactory.getLogger(SampleIndexOnlyVariantQueryExecutor.class); @@ -82,7 +78,6 @@ public SampleIndexOnlyVariantQueryExecutor(VariantHadoopDBAdaptor dbAdaptor, Sam super(dbAdaptor.getMetadataManager(), storageEngineId, options); this.sampleIndexDBAdaptor = sampleIndexDBAdaptor; this.dbAdaptor = dbAdaptor; - variantQueryParser = new VariantQueryParser(null, getMetadataManager()); variantQueryProjectionParser = new VariantQueryProjectionParser(getMetadataManager()); partialDataBufferSize = options.getInt(SAMPLE_INDEX_QUERY_SAMPLE_INDEX_ONLY_PD_BUFFER.key(), SAMPLE_INDEX_QUERY_SAMPLE_INDEX_ONLY_PD_BUFFER.defaultValue()); @@ -101,26 +96,16 @@ public boolean canUseThisExecutor(Query query, QueryOptions options) { return false; } - @Override - public DataResult count(Query query) { - StopWatch stopWatch = StopWatch.createStarted(); - SampleIndexQuery sampleIndexQuery = sampleIndexDBAdaptor.parseSampleIndexQuery(query); - long count = sampleIndexDBAdaptor.count(sampleIndexQuery); - return new DataResult<>(((int) stopWatch.getTime(TimeUnit.MILLISECONDS)), Collections.emptyList(), 1, - Collections.singletonList(count), count); - } - /** * Fetch results exclusively from SampleSecondaryIndex. * - * @param inputQuery Query - * @param options Options + * @param variantQuery Query * @param iterator Shall the resulting object be an iterator instead of a DataResult * @return DataResult or Iterator with the variants that matches the query */ @Override - protected Object getOrIterator(Query inputQuery, QueryOptions options, boolean iterator) { - Query query = new Query(inputQuery); + protected Object getOrIterator(ParsedVariantQuery variantQuery, boolean iterator) { + Query query = new Query(variantQuery.getQuery()); query.put(SampleIndexQueryParser.INCLUDE_PARENTS_COLUMN, true); SampleIndexQuery sampleIndexQuery = sampleIndexDBAdaptor.parseSampleIndexQuery(query); @@ -128,7 +113,7 @@ protected Object getOrIterator(Query inputQuery, QueryOptions options, boolean i boolean count; Future asyncCountFuture; - if (shouldGetCount(options, iterator)) { + if (shouldGetCount(variantQuery.getInputOptions(), iterator)) { count = true; asyncCountFuture = THREAD_POOL.submit(() -> { StopWatch stopWatch = StopWatch.createStarted(); @@ -141,13 +126,12 @@ protected Object getOrIterator(Query inputQuery, QueryOptions options, boolean i asyncCountFuture = null; } - VariantDBIterator variantIterator = getVariantDBIterator(sampleIndexQuery, inputQuery, options); + VariantDBIterator variantIterator = getVariantDBIterator(sampleIndexQuery, variantQuery); if (iterator) { return variantIterator; } else { - VariantQueryResult result = - addSamplesMetadataIfRequested(variantIterator.toDataResult(), inputQuery, options, getMetadataManager()); + VariantQueryResult result = variantIterator.toDataResult(variantQuery); if (count) { result.setApproximateCount(false); try { @@ -161,8 +145,8 @@ protected Object getOrIterator(Query inputQuery, QueryOptions options, boolean i } } - private VariantDBIterator getVariantDBIterator(SampleIndexQuery sampleIndexQuery, Query inputQuery, QueryOptions options) { - ParsedVariantQuery parsedQuery = variantQueryParser.parseQuery(inputQuery, options, true); + private VariantDBIterator getVariantDBIterator(SampleIndexQuery sampleIndexQuery, ParsedVariantQuery parsedQuery) { + QueryOptions options = parsedQuery.getInputOptions(); VariantDBIterator variantIterator; if (parsedQuery.getProjection().getStudyIds().isEmpty()) { logger.info("Using sample index iterator Iterator"); @@ -174,9 +158,9 @@ private VariantDBIterator getVariantDBIterator(SampleIndexQuery sampleIndexQuery try { rawIterator = sampleIndexDBAdaptor.rawIterator(sampleIndexQuery, options); } catch (IOException e) { - throw VariantQueryException.internalException(e).setQuery(inputQuery); + throw VariantQueryException.internalException(e).setQuery(parsedQuery.getInputQuery()); } - boolean includeAll = inputQuery.getBoolean("includeAllFromSampleIndex", false); + boolean includeAll = parsedQuery.getInputQuery().getBoolean("includeAllFromSampleIndex", false); SampleVariantIndexEntryToVariantConverter converter = new SampleVariantIndexEntryToVariantConverter( parsedQuery, sampleIndexQuery, dbAdaptor.getMetadataManager(), includeAll); variantIterator = VariantDBIterator.wrapper(Iterators.transform(rawIterator, converter::convert)); diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/index/SampleIndexVariantAggregationExecutor.java b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/index/SampleIndexVariantAggregationExecutor.java index c27c2294e79..1bf855183b7 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/index/SampleIndexVariantAggregationExecutor.java +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/index/SampleIndexVariantAggregationExecutor.java @@ -9,7 +9,7 @@ import org.opencb.commons.datastore.core.FacetField; import org.opencb.commons.datastore.core.Query; import org.opencb.commons.datastore.core.QueryOptions; -import org.opencb.opencga.core.response.VariantQueryResult; +import org.opencb.opencga.storage.core.variant.query.VariantQueryResult; import org.opencb.opencga.storage.core.io.bit.BitBuffer; import org.opencb.opencga.storage.core.metadata.VariantStorageMetadataManager; import org.opencb.opencga.storage.core.utils.iterators.CloseableIterator; @@ -144,7 +144,7 @@ protected VariantQueryResult aggregation(Query query, QueryOptions o } return new VariantQueryResult<>((int) stopWatch.getTime(TimeUnit.MILLISECONDS), 1, numMatches, Collections.emptyList(), - fields, null, SampleIndexVariantQueryExecutor.SAMPLE_INDEX_TABLE_SOURCE); + fields, SampleIndexVariantQueryExecutor.SAMPLE_INDEX_TABLE_SOURCE); } } diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/index/SampleIndexVariantQueryExecutor.java b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/index/SampleIndexVariantQueryExecutor.java index 64cf8669153..06a27a4156d 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/index/SampleIndexVariantQueryExecutor.java +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/index/SampleIndexVariantQueryExecutor.java @@ -3,17 +3,17 @@ import org.apache.commons.lang3.concurrent.BasicThreadFactory; import org.apache.commons.lang3.time.StopWatch; import org.opencb.biodata.models.variant.Variant; -import org.opencb.commons.datastore.core.DataResult; import org.opencb.commons.datastore.core.ObjectMap; import org.opencb.commons.datastore.core.Query; import org.opencb.commons.datastore.core.QueryOptions; import org.opencb.opencga.core.common.TimeUtils; -import org.opencb.opencga.core.response.VariantQueryResult; import org.opencb.opencga.storage.core.variant.VariantStorageOptions; import org.opencb.opencga.storage.core.variant.adaptors.VariantQueryException; import org.opencb.opencga.storage.core.variant.adaptors.VariantQueryParam; import org.opencb.opencga.storage.core.variant.adaptors.iterators.MultiVariantDBIterator; import org.opencb.opencga.storage.core.variant.adaptors.iterators.VariantDBIteratorWithCounts; +import org.opencb.opencga.storage.core.variant.query.ParsedVariantQuery; +import org.opencb.opencga.storage.core.variant.query.VariantQueryResult; import org.opencb.opencga.storage.core.variant.query.VariantQueryUtils; import org.opencb.opencga.storage.core.variant.query.executors.AbstractTwoPhasedVariantQueryExecutor; import org.opencb.opencga.storage.hadoop.variant.adaptors.VariantHadoopDBAdaptor; @@ -31,7 +31,6 @@ import static org.opencb.opencga.storage.core.variant.adaptors.VariantQueryParam.ID; import static org.opencb.opencga.storage.core.variant.adaptors.VariantQueryParam.REGION; -import static org.opencb.opencga.storage.core.variant.query.VariantQueryUtils.addSamplesMetadataIfRequested; /** * Created on 01/04/19. @@ -66,11 +65,6 @@ public boolean canUseThisExecutor(Query query, QueryOptions options) { return false; } - @Override - public DataResult count(Query query) { - throw new UnsupportedOperationException("Count not implemented in " + getClass()); - } - @Override protected long primaryCount(Query query, QueryOptions options) { SampleIndexQuery sampleIndexQuery = sampleIndexDBAdaptor.parseSampleIndexQuery(query); @@ -81,24 +75,25 @@ protected long primaryCount(Query query, QueryOptions options) { * Intersect result of SampleIndexTable and full phoenix query. * Use {@link org.opencb.opencga.storage.core.variant.adaptors.iterators.MultiVariantDBIterator}. * - * @param inputQuery Query - * @param options Options + * @param variantQuery Parsed query * @param iterator Shall the resulting object be an iterator instead of a DataResult * @return DataResult or Iterator with the variants that matches the query */ @Override - protected Object getOrIterator(Query inputQuery, QueryOptions options, boolean iterator) { - Query query = new Query(inputQuery); + protected Object getOrIterator(ParsedVariantQuery variantQuery, boolean iterator) { + Query query = new Query(variantQuery.getQuery()); SampleIndexQuery sampleIndexQuery = sampleIndexDBAdaptor.parseSampleIndexQuery(query); - return getOrIterator(query, options, iterator, sampleIndexQuery); + return getOrIterator(variantQuery, iterator, sampleIndexQuery); } - protected Object getOrIterator(Query query, QueryOptions inputOptions, boolean iterator, SampleIndexQuery sampleIndexQuery) { + protected Object getOrIterator(ParsedVariantQuery variantQuery, boolean iterator, SampleIndexQuery sampleIndexQuery) { logger.info("HBase SampleIndex intersect"); + QueryOptions inputOptions = variantQuery.getInputOptions(); + Query uncoveredQuery = new Query(sampleIndexQuery.getUncoveredQuery()); Future asyncCountFuture; boolean asyncCount; - if (shouldGetApproximateCount(inputOptions, iterator) && queryFiltersCovered(query)) { + if (shouldGetApproximateCount(inputOptions, iterator) && queryFiltersCovered(uncoveredQuery)) { asyncCount = true; asyncCountFuture = THREAD_POOL.submit(() -> { StopWatch stopWatch = StopWatch.createStarted(); @@ -120,10 +115,10 @@ protected Object getOrIterator(Query query, QueryOptions inputOptions, boolean i int batchSize = inputOptions.getInt("multiIteratorBatchSize", 200); if (iterator) { // SampleIndex iterator will be closed when closing the variants iterator - return dbAdaptor.iterator(variants, query, inputOptions, batchSize); + return dbAdaptor.iterator(variants, uncoveredQuery, inputOptions, batchSize); } else { - int skip = getSkip(inputOptions); - int limit = getLimit(inputOptions); + int skip = variantQuery.getSkip(); + int limit = variantQuery.getLimitOr(-1); int samplingSize = asyncCount ? 0 : getSamplingSize(inputOptions, DEFAULT_SAMPLING_SIZE, iterator); int tmpLimit = Math.max(limit, samplingSize); @@ -139,9 +134,8 @@ protected Object getOrIterator(Query query, QueryOptions inputOptions, boolean i public void close() throws Exception { // Do not close this iterator! We'll need to keep iterating to get the approximate count } - }, query, options, batchSize); - VariantQueryResult result = - addSamplesMetadataIfRequested(variantDBIterator.toDataResult(), query, options, getMetadataManager()); + }, uncoveredQuery, options, batchSize); + VariantQueryResult result = variantDBIterator.toDataResult(variantQuery); if (result.getNumResults() < tmpLimit) { // Not an approximate count! @@ -162,7 +156,7 @@ public void close() throws Exception { inputOptions.get(QueryOptions.COUNT)); numTotalResultsOptions.put(VariantStorageOptions.APPROXIMATE_COUNT.key(), inputOptions.get(VariantStorageOptions.APPROXIMATE_COUNT.key())); - setNumTotalResults(variantDBIterator, variants, result, sampleIndexQuery, query, numTotalResultsOptions); + setNumTotalResults(variantDBIterator, variants, result, sampleIndexQuery, uncoveredQuery, numTotalResultsOptions); } // Ensure limit diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/index/query/SampleIndexQuery.java b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/index/query/SampleIndexQuery.java index 664ace07747..4a4803ff6a4 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/index/query/SampleIndexQuery.java +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/index/query/SampleIndexQuery.java @@ -4,6 +4,7 @@ import org.opencb.biodata.models.core.Region; import org.opencb.biodata.models.variant.Variant; import org.opencb.biodata.models.variant.avro.VariantType; +import org.opencb.commons.datastore.core.Query; import org.opencb.opencga.storage.core.variant.query.Values; import org.opencb.opencga.storage.hadoop.variant.index.family.GenotypeCodec; import org.opencb.opencga.storage.hadoop.variant.index.sample.SampleIndexSchema; @@ -49,6 +50,8 @@ public class SampleIndexQuery { private final Set mendelianErrorSet; private final MendelianErrorType mendelianErrorType; private final boolean includeParentColumns; + + private final Query uncoveredQuery; private final QueryOperation queryOperation; public enum MendelianErrorType { @@ -73,6 +76,7 @@ public SampleIndexQuery(Collection locusQueries, SampleIndexQuery qu this.mendelianErrorSet = query.mendelianErrorSet; this.mendelianErrorType = query.mendelianErrorType; this.includeParentColumns = query.includeParentColumns; + this.uncoveredQuery = query.uncoveredQuery; this.queryOperation = query.queryOperation; } @@ -83,7 +87,7 @@ public SampleIndexQuery(SampleIndexSchema schema, Collection locusQu Map> fileFilterMap, SampleAnnotationIndexQuery annotationIndexQuery, Set mendelianErrorSet, MendelianErrorType mendelianErrorType, boolean includeParentColumns, - QueryOperation queryOperation) { + QueryOperation queryOperation, Query uncoveredQuery) { this.schema = schema; this.locusQueries = locusQueries; this.extendedFilteringRegion = extendedFilteringRegion; @@ -100,6 +104,7 @@ public SampleIndexQuery(SampleIndexSchema schema, Collection locusQu this.mendelianErrorType = mendelianErrorType; this.includeParentColumns = includeParentColumns; this.queryOperation = queryOperation; + this.uncoveredQuery = uncoveredQuery; } public SampleIndexSchema getSchema() { @@ -227,6 +232,10 @@ public boolean isIncludeParentColumns() { return includeParentColumns; } + public Query getUncoveredQuery() { + return uncoveredQuery; + } + public QueryOperation getQueryOperation() { return queryOperation; } diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/index/query/SingleSampleIndexQuery.java b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/index/query/SingleSampleIndexQuery.java index 35a9e67e718..51f44824872 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/index/query/SingleSampleIndexQuery.java +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/index/query/SingleSampleIndexQuery.java @@ -36,7 +36,8 @@ protected SingleSampleIndexQuery(SampleIndexQuery query, String sample, List findParents(Set childrenSet, Map> parentsMap) { diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/io/VariantExporterDriver.java b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/io/VariantExporterDriver.java index 196ab0e1689..aa342c10a92 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/io/VariantExporterDriver.java +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/io/VariantExporterDriver.java @@ -33,6 +33,7 @@ import org.opencb.opencga.storage.core.variant.query.ParsedVariantQuery; import org.opencb.opencga.storage.core.variant.query.VariantQueryParser; import org.opencb.opencga.storage.hadoop.variant.AbstractVariantsTableDriver; +import org.opencb.opencga.storage.hadoop.variant.HadoopVariantQueryParser; import org.opencb.opencga.storage.hadoop.variant.adaptors.VariantHBaseQueryParser; import org.opencb.opencga.storage.hadoop.variant.adaptors.phoenix.VariantSqlQueryParser; import org.opencb.opencga.storage.hadoop.variant.index.sample.SampleIndexDBAdaptor; @@ -188,7 +189,7 @@ protected Job setupJob(Job job, String archiveTable, String variantTable) throws VariantMapReduceUtil.setNoneReduce(job); } - VariantQueryParser variantQueryParser = new VariantQueryParser(null, getMetadataManager()); + VariantQueryParser variantQueryParser = new HadoopVariantQueryParser(null, getMetadataManager()); ParsedVariantQuery variantQuery = variantQueryParser.parseQuery(query, options); Query query = variantQuery.getQuery(); if (VariantHBaseQueryParser.isSupportedQuery(query)) { diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/mr/VariantMapReduceUtil.java b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/mr/VariantMapReduceUtil.java index 623deec75da..367196742db 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/mr/VariantMapReduceUtil.java +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/mr/VariantMapReduceUtil.java @@ -29,11 +29,11 @@ import org.opencb.opencga.core.config.storage.SampleIndexConfiguration; import org.opencb.opencga.storage.core.metadata.VariantStorageMetadataManager; import org.opencb.opencga.storage.core.variant.adaptors.VariantQueryParam; -import org.opencb.opencga.storage.core.variant.query.VariantQueryParser; import org.opencb.opencga.storage.core.variant.query.VariantQueryUtils; import org.opencb.opencga.storage.hadoop.utils.AbstractHBaseDriver; import org.opencb.opencga.storage.hadoop.variant.AbstractVariantsTableDriver; import org.opencb.opencga.storage.hadoop.variant.GenomeHelper; +import org.opencb.opencga.storage.hadoop.variant.HadoopVariantQueryParser; import org.opencb.opencga.storage.hadoop.variant.HadoopVariantStorageOptions; import org.opencb.opencga.storage.hadoop.variant.adaptors.VariantHBaseQueryParser; import org.opencb.opencga.storage.hadoop.variant.adaptors.VariantHadoopDBAdaptor; @@ -153,7 +153,7 @@ public static void initTableMapperJobFromPhoenix(Job job, String variantTable, S public static void initVariantMapperJob(Job job, Class mapperClass, String variantTable, VariantStorageMetadataManager metadataManager, Query query, QueryOptions queryOptions, boolean skipSampleIndex) throws IOException { - query = new VariantQueryParser(null, metadataManager).preProcessQuery(query, queryOptions); + query = new HadoopVariantQueryParser(null, metadataManager).preProcessQuery(query, queryOptions); setQuery(job, query); setQueryOptions(job, queryOptions); @@ -266,7 +266,7 @@ public static void initVariantRowMapperJob(Job job, Class mapperClass, String variantTable, VariantStorageMetadataManager metadataManager, Query query, QueryOptions queryOptions, boolean skipSampleIndex) throws IOException { - query = new VariantQueryParser(null, metadataManager).preProcessQuery(query, queryOptions); + query = new HadoopVariantQueryParser(null, metadataManager).preProcessQuery(query, queryOptions); setQuery(job, query); setQueryOptions(job, queryOptions); diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/test/java/org/opencb/opencga/storage/hadoop/variant/HadoopVariantStorageEngineSVTest.java b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/test/java/org/opencb/opencga/storage/hadoop/variant/HadoopVariantStorageEngineSVTest.java index b1bd9d84879..09bbce14acd 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/test/java/org/opencb/opencga/storage/hadoop/variant/HadoopVariantStorageEngineSVTest.java +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/test/java/org/opencb/opencga/storage/hadoop/variant/HadoopVariantStorageEngineSVTest.java @@ -7,8 +7,7 @@ import org.opencb.biodata.models.variant.Variant; import org.opencb.commons.datastore.core.Query; import org.opencb.commons.datastore.core.QueryOptions; -import org.opencb.opencga.core.api.ParamConstants; -import org.opencb.opencga.core.response.VariantQueryResult; +import org.opencb.opencga.storage.core.variant.query.VariantQueryResult; import org.opencb.opencga.core.testclassification.duration.LongTests; import org.opencb.opencga.storage.core.variant.VariantStorageEngineSVTest; import org.opencb.opencga.storage.core.variant.adaptors.GenotypeClass; diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/test/java/org/opencb/opencga/storage/hadoop/variant/adaptors/HadoopVariantDBAdaptorMultiFileTest.java b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/test/java/org/opencb/opencga/storage/hadoop/variant/adaptors/HadoopVariantDBAdaptorMultiFileTest.java index be47dd08890..bebcb5ce4da 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/test/java/org/opencb/opencga/storage/hadoop/variant/adaptors/HadoopVariantDBAdaptorMultiFileTest.java +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/test/java/org/opencb/opencga/storage/hadoop/variant/adaptors/HadoopVariantDBAdaptorMultiFileTest.java @@ -10,8 +10,7 @@ import org.opencb.commons.datastore.core.ObjectMap; import org.opencb.commons.datastore.core.Query; import org.opencb.commons.datastore.core.QueryOptions; -import org.opencb.opencga.core.api.ParamConstants; -import org.opencb.opencga.core.response.VariantQueryResult; +import org.opencb.opencga.storage.core.variant.query.VariantQueryResult; import org.opencb.opencga.core.testclassification.duration.MediumTests; import org.opencb.opencga.storage.core.variant.VariantStorageEngine; import org.opencb.opencga.storage.core.variant.VariantStorageOptions; diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/test/java/org/opencb/opencga/storage/hadoop/variant/adaptors/HadoopVariantDBAdaptorNativeTest.java b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/test/java/org/opencb/opencga/storage/hadoop/variant/adaptors/HadoopVariantDBAdaptorNativeTest.java index 7d6b6f19ba5..e03253739d3 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/test/java/org/opencb/opencga/storage/hadoop/variant/adaptors/HadoopVariantDBAdaptorNativeTest.java +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/test/java/org/opencb/opencga/storage/hadoop/variant/adaptors/HadoopVariantDBAdaptorNativeTest.java @@ -9,7 +9,7 @@ import org.opencb.biodata.models.variant.Variant; import org.opencb.commons.datastore.core.Query; import org.opencb.commons.datastore.core.QueryOptions; -import org.opencb.opencga.core.response.VariantQueryResult; +import org.opencb.opencga.storage.core.variant.query.VariantQueryResult; import org.opencb.opencga.core.testclassification.duration.LongTests; import org.opencb.opencga.storage.core.variant.adaptors.VariantQueryParam; import org.opencb.opencga.storage.core.variant.query.VariantQueryUtils; diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/test/java/org/opencb/opencga/storage/hadoop/variant/gaps/FillGapsTest.java b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/test/java/org/opencb/opencga/storage/hadoop/variant/gaps/FillGapsTest.java index 3ae2a36bfbc..a2e6699180d 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/test/java/org/opencb/opencga/storage/hadoop/variant/gaps/FillGapsTest.java +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/test/java/org/opencb/opencga/storage/hadoop/variant/gaps/FillGapsTest.java @@ -18,7 +18,7 @@ import org.opencb.commons.datastore.core.QueryOptions; import org.opencb.opencga.core.models.operations.variant.VariantAggregateFamilyParams; import org.opencb.opencga.core.models.operations.variant.VariantAggregateParams; -import org.opencb.opencga.core.response.VariantQueryResult; +import org.opencb.opencga.storage.core.variant.query.VariantQueryResult; import org.opencb.opencga.core.testclassification.duration.LongTests; import org.opencb.opencga.storage.core.StoragePipelineResult; import org.opencb.opencga.storage.core.metadata.models.StudyMetadata; diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/test/java/org/opencb/opencga/storage/hadoop/variant/index/family/FamilyIndexTest.java b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/test/java/org/opencb/opencga/storage/hadoop/variant/index/family/FamilyIndexTest.java index ccafd14be63..f67d5734d7c 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/test/java/org/opencb/opencga/storage/hadoop/variant/index/family/FamilyIndexTest.java +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/test/java/org/opencb/opencga/storage/hadoop/variant/index/family/FamilyIndexTest.java @@ -16,7 +16,7 @@ import org.opencb.commons.datastore.core.QueryOptions; import org.opencb.opencga.core.api.ParamConstants; import org.opencb.opencga.core.models.operations.variant.VariantAggregateFamilyParams; -import org.opencb.opencga.core.response.VariantQueryResult; +import org.opencb.opencga.storage.core.variant.query.VariantQueryResult; import org.opencb.opencga.core.testclassification.duration.MediumTests; import org.opencb.opencga.storage.core.metadata.models.Trio; import org.opencb.opencga.storage.core.variant.VariantStorageBaseTest; diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/test/java/org/opencb/opencga/storage/hadoop/variant/index/sample/SampleIndexDBAdaptorTest.java b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/test/java/org/opencb/opencga/storage/hadoop/variant/index/sample/SampleIndexDBAdaptorTest.java index 03e8b3cd4fb..a46a3a5c99b 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/test/java/org/opencb/opencga/storage/hadoop/variant/index/sample/SampleIndexDBAdaptorTest.java +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/test/java/org/opencb/opencga/storage/hadoop/variant/index/sample/SampleIndexDBAdaptorTest.java @@ -45,7 +45,7 @@ public void testSampleIdFF() throws Exception { SampleIndexQuery query = new SampleIndexQuery(SampleIndexSchema.defaultSampleIndexSchema(), Collections.emptyList(), 0, null, "ST", Collections.singletonMap(sampleName, Collections.singletonList("0/1")), Collections.emptySet(), null, Collections.emptyMap(), Collections.emptyMap(), Collections.emptyMap(), new SampleAnnotationIndexQuery(SampleIndexSchema.defaultSampleIndexSchema()), - Collections.emptySet(), null, false, VariantQueryUtils.QueryOperation.AND); + Collections.emptySet(), null, false, VariantQueryUtils.QueryOperation.AND, null); new SampleIndexDBAdaptor(new HBaseManager(new Configuration()), null, metadataManager).parse(query.forSample(sampleName), null); } diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/test/java/org/opencb/opencga/storage/hadoop/variant/index/sample/SampleIndexDuplicatedVariantsTest.java b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/test/java/org/opencb/opencga/storage/hadoop/variant/index/sample/SampleIndexDuplicatedVariantsTest.java index 6a9c35eb0da..be83e365bed 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/test/java/org/opencb/opencga/storage/hadoop/variant/index/sample/SampleIndexDuplicatedVariantsTest.java +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/test/java/org/opencb/opencga/storage/hadoop/variant/index/sample/SampleIndexDuplicatedVariantsTest.java @@ -63,7 +63,7 @@ public void test2FilesSampleIndex() throws Exception { SampleIndexOnlyVariantQueryExecutor queryExecutor = new SampleIndexOnlyVariantQueryExecutor(dbAdaptor, sampleIndexDBAdaptor, "", new ObjectMap()); List expectedVariants = new ArrayList<>(); - queryExecutor.iterator(new VariantQuery().sample("s1"), new QueryOptions()).forEachRemaining(expectedVariants::add); + queryExecutor.iterator(variantStorageEngine.parseQuery(new VariantQuery().sample("s1"), new QueryOptions())).forEachRemaining(expectedVariants::add); int studyId = engine.getMetadataManager().getStudyId(STUDY_NAME); String actualSampleIndexTableName = sampleIndexDBAdaptor.getSampleIndexTableNameLatest(studyId); @@ -81,7 +81,7 @@ public void test2FilesSampleIndex() throws Exception { VariantHbaseTestUtils.printVariants(dbAdaptor, newOutputUri()); List actualVariants = new ArrayList<>(); - queryExecutor.iterator(new VariantQuery().sample("s1"), new QueryOptions()).forEachRemaining(actualVariants::add); + queryExecutor.iterator(variantStorageEngine.parseQuery(new VariantQuery().sample("s1"), new QueryOptions())).forEachRemaining(actualVariants::add); Assert.assertEquals(expectedVariants, actualVariants); @@ -105,7 +105,7 @@ public void test3FilesSampleIndex() throws Exception { SampleIndexOnlyVariantQueryExecutor queryExecutor = new SampleIndexOnlyVariantQueryExecutor(dbAdaptor, sampleIndexDBAdaptor, "", new ObjectMap()); List expectedVariants = new ArrayList<>(); - queryExecutor.iterator(new VariantQuery().sample("s1"), new QueryOptions()).forEachRemaining(expectedVariants::add); + queryExecutor.iterator(variantStorageEngine.parseQuery(new VariantQuery().sample("s1"), new QueryOptions())).forEachRemaining(expectedVariants::add); int studyId = engine.getMetadataManager().getStudyId(STUDY_NAME); String actualSampleIndexTableName = sampleIndexDBAdaptor.getSampleIndexTableNameLatest(studyId); @@ -123,7 +123,7 @@ public void test3FilesSampleIndex() throws Exception { VariantHbaseTestUtils.printVariants(dbAdaptor, newOutputUri()); List actualVariants = new ArrayList<>(); - queryExecutor.iterator(new VariantQuery().sample("s1"), new QueryOptions()).forEachRemaining(actualVariants::add); + queryExecutor.iterator(variantStorageEngine.parseQuery(new VariantQuery().sample("s1"), new QueryOptions())).forEachRemaining(actualVariants::add); Assert.assertEquals(expectedVariants, actualVariants); diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/test/java/org/opencb/opencga/storage/hadoop/variant/index/sample/SampleIndexEntryFilterTest.java b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/test/java/org/opencb/opencga/storage/hadoop/variant/index/sample/SampleIndexEntryFilterTest.java index f4989f9ff79..76cc13feeb9 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/test/java/org/opencb/opencga/storage/hadoop/variant/index/sample/SampleIndexEntryFilterTest.java +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/test/java/org/opencb/opencga/storage/hadoop/variant/index/sample/SampleIndexEntryFilterTest.java @@ -279,7 +279,7 @@ private SingleSampleIndexQuery getSingleSampleIndexQuery(SampleAnnotationIndexQu private SingleSampleIndexQuery getSingleSampleIndexQuery(SampleAnnotationIndexQuery annotationIndexQuery, Map> fileFilterMap) { return new SampleIndexQuery( - schema, Collections.emptyList(), 0, null, "study", Collections.singletonMap("S1", Arrays.asList("0/1", "1/1")), Collections.emptySet(), null, Collections.emptyMap(), Collections.emptyMap(), fileFilterMap, annotationIndexQuery, Collections.emptySet(), null, false, VariantQueryUtils.QueryOperation.AND) + schema, Collections.emptyList(), 0, null, "study", Collections.singletonMap("S1", Arrays.asList("0/1", "1/1")), Collections.emptySet(), null, Collections.emptyMap(), Collections.emptyMap(), fileFilterMap, annotationIndexQuery, Collections.emptySet(), null, false, VariantQueryUtils.QueryOperation.AND, null) .forSample("S1"); } } \ No newline at end of file diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/test/java/org/opencb/opencga/storage/hadoop/variant/index/sample/SampleIndexQueryParserTest.java b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/test/java/org/opencb/opencga/storage/hadoop/variant/index/sample/SampleIndexQueryParserTest.java index 0eafe0ca875..7ae4e36f3ec 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/test/java/org/opencb/opencga/storage/hadoop/variant/index/sample/SampleIndexQueryParserTest.java +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/test/java/org/opencb/opencga/storage/hadoop/variant/index/sample/SampleIndexQueryParserTest.java @@ -26,8 +26,8 @@ import org.opencb.opencga.storage.core.variant.VariantStorageOptions; import org.opencb.opencga.storage.core.variant.dummy.DummyVariantStorageMetadataDBAdaptorFactory; import org.opencb.opencga.storage.core.variant.query.Values; -import org.opencb.opencga.storage.core.variant.query.VariantQueryParser; import org.opencb.opencga.storage.core.variant.query.VariantQueryUtils; +import org.opencb.opencga.storage.hadoop.variant.HadoopVariantQueryParser; import org.opencb.opencga.storage.hadoop.variant.index.annotation.AnnotationIndexConverter; import org.opencb.opencga.storage.hadoop.variant.index.core.IndexField; import org.opencb.opencga.storage.hadoop.variant.index.core.RangeIndexField; @@ -127,7 +127,7 @@ public void setUp() throws Exception { } private SampleIndexQuery parse(final Query query) { - Query newQuery = new VariantQueryParser(null, mm).preProcessQuery(query, new QueryOptions()); + Query newQuery = new HadoopVariantQueryParser(null, mm).preProcessQuery(query, new QueryOptions()); query.clear(); query.putAll(newQuery); return sampleIndexQueryParser.parse(query); diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/test/java/org/opencb/opencga/storage/hadoop/variant/index/sample/SampleIndexTest.java b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/test/java/org/opencb/opencga/storage/hadoop/variant/index/sample/SampleIndexTest.java index 922c2648f4d..1ee4944733e 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/test/java/org/opencb/opencga/storage/hadoop/variant/index/sample/SampleIndexTest.java +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/test/java/org/opencb/opencga/storage/hadoop/variant/index/sample/SampleIndexTest.java @@ -26,7 +26,7 @@ import org.opencb.opencga.core.config.storage.IndexFieldConfiguration; import org.opencb.opencga.core.config.storage.SampleIndexConfiguration; import org.opencb.opencga.core.models.variant.VariantAnnotationConstants; -import org.opencb.opencga.core.response.VariantQueryResult; +import org.opencb.opencga.storage.core.variant.query.VariantQueryResult; import org.opencb.opencga.core.testclassification.duration.LongTests; import org.opencb.opencga.storage.core.exceptions.StorageEngineException; import org.opencb.opencga.storage.core.metadata.models.SampleMetadata; @@ -463,26 +463,26 @@ public void testLocusQueryOverlap() throws Exception { VariantQuery query = new VariantQuery().study(STUDY_NAME_5).sample("NA19600"); // System.out.println("query = " + query.toJson()); List variants = sampleIndexDBAdaptor.iterator(new Query(query), new QueryOptions()) - .toDataResult().getResults(); + .toList(); assertEquals(2, variants.size()); query.region("1:2000200-5500000"); // System.out.println("query = " + query.toJson()); variants = sampleIndexDBAdaptor.iterator(new Query(query), new QueryOptions()) - .toDataResult().getResults(); + .toList(); assertEquals(2, variants.size()); query.region("1:200-2500000"); // System.out.println("query = " + query.toJson()); variants = sampleIndexDBAdaptor.iterator(new Query(query), new QueryOptions()) - .toDataResult().getResults(); + .toList(); assertEquals(1, variants.size()); assertEquals("1:1000001-4000000:-:", variants.get(0).toString()); query.region("1:2000200-2500000"); // System.out.println("query = " + query.toJson()); variants = sampleIndexDBAdaptor.iterator(new Query(query), new QueryOptions()) - .toDataResult().getResults(); + .toList(); assertEquals(1, variants.size()); assertEquals("1:1000001-4000000:-:", variants.get(0).toString()); } @@ -668,10 +668,10 @@ public SampleIndexQuery testQueryIndex(Query testQuery, Query query, boolean sam SampleIndexQuery indexQuery = sampleIndexDBAdaptor.parseSampleIndexQuery(sampleIndexVariantQuery); // int onlyIndex = (int) ((HadoopVariantStorageEngine) variantStorageEngine).getSampleIndexDBAdaptor() // .count(indexQuery, "NA19600"); - DataResult result = ((HadoopVariantStorageEngine) variantStorageEngine).getSampleIndexDBAdaptor() - .iterator(indexQuery).toDataResult(); + List result = ((HadoopVariantStorageEngine) variantStorageEngine).getSampleIndexDBAdaptor() + .iterator(indexQuery).toList(); // System.out.println("result.getResults() = " + result.getResults()); - List onlyIndex = result.getResults().stream().map(Variant::toString).sorted().collect(toList()); + List onlyIndex = result.stream().map(Variant::toString).sorted().collect(toList()); // Query SampleIndex+DBAdaptor System.out.println("#Query SampleIndex+DBAdaptor"); @@ -815,7 +815,7 @@ public void testCount() throws StorageEngineException { System.out.println("Count = " + actualCount); stopWatch = StopWatch.createStarted(); - long actualCountIterator = sampleIndexDBAdaptor.iterator(sampleIndexDBAdaptor.parseSampleIndexQuery(new Query(query))).toDataResult().getNumResults(); + long actualCountIterator = sampleIndexDBAdaptor.iterator(sampleIndexDBAdaptor.parseSampleIndexQuery(new Query(query))).toList().size(); System.out.println("---"); System.out.println("Count indexTable iterator " + stopWatch.getTime(TimeUnit.MILLISECONDS) / 1000.0); System.out.println("Count = " + actualCountIterator); @@ -1179,24 +1179,24 @@ private void testSampleIndexOnlyVariantQueryExecutor(VariantQuery query, QueryOp private void testSampleIndexOnlyVariantQueryExecutor(VariantQuery query, QueryOptions options, Class expected, Function mapper) { - VariantQueryExecutor variantQueryExecutor = variantStorageEngine.getVariantQueryExecutor( - query, - options); + ParsedVariantQuery variantQuery = variantStorageEngine.parseQuery(query, options); + + VariantQueryExecutor variantQueryExecutor = variantStorageEngine.getVariantQueryExecutor(variantQuery); assertEquals(expected, variantQueryExecutor.getClass()); - ParsedVariantQuery variantQuery = variantStorageEngine.parseQuery(query, options); List expectedVariants = new ArrayList<>(1000); - dbAdaptor.iterator(variantQuery, new QueryOptions(options)) + dbAdaptor.iterator(variantQuery) .forEachRemaining(expectedVariants::add); List actualVariants = new ArrayList<>(1000); - variantQueryExecutor.iterator(variantQuery.getQuery(), options) + variantQueryExecutor.iterator(variantStorageEngine.parseQuery(variantQuery.getQuery(), options)) .forEachRemaining(actualVariants::add); - VariantQueryResult result = variantQueryExecutor.get(variantQuery.getQuery(), new QueryOptions(options) + ParsedVariantQuery limitedQuery = variantStorageEngine.parseQuery(variantQuery.getQuery(), new QueryOptions(options) .append(QueryOptions.LIMIT, 10) .append(QueryOptions.COUNT, true)); + VariantQueryResult result = variantQueryExecutor.get(limitedQuery); assertEquals(10, result.getNumResults()); assertEquals(10, result.getResults().size()); long count = result.getNumMatches(); diff --git a/opencga-storage/opencga-storage-server/src/main/java/org/opencb/opencga/storage/server/rest/VariantRestWebService.java b/opencga-storage/opencga-storage-server/src/main/java/org/opencb/opencga/storage/server/rest/VariantRestWebService.java index 00832a76dd9..c6292d4f2f1 100644 --- a/opencga-storage/opencga-storage-server/src/main/java/org/opencb/opencga/storage/server/rest/VariantRestWebService.java +++ b/opencga-storage/opencga-storage-server/src/main/java/org/opencb/opencga/storage/server/rest/VariantRestWebService.java @@ -20,7 +20,7 @@ import org.opencb.commons.datastore.core.DataResult; import org.opencb.commons.datastore.core.Query; import org.opencb.commons.datastore.core.QueryOptions; -import org.opencb.opencga.core.response.VariantQueryResult; +import org.opencb.opencga.storage.core.variant.query.VariantQueryResult; import org.opencb.opencga.storage.core.StorageEngineFactory; import org.opencb.opencga.storage.core.exceptions.StorageEngineException; import org.opencb.opencga.storage.core.variant.adaptors.VariantDBAdaptor; From 2721cba65bea90ec8b34713c61ec963e94aae87b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacobo=20Coll=20Morag=C3=B3n?= Date: Tue, 16 Apr 2024 15:31:40 +0100 Subject: [PATCH 26/85] storage: Add an event when returning invalid/outdated stats #TASK-5876 --- .../variant/query/ParsedVariantQuery.java | 12 ++++++ .../variant/query/VariantQueryResult.java | 31 ++++++++++----- .../projection/VariantQueryProjection.java | 11 ++++++ .../VariantQueryProjectionParser.java | 8 +++- .../stats/VariantStatisticsManagerTest.java | 39 ++++++++++++++++++- 5 files changed, 90 insertions(+), 11 deletions(-) diff --git a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/ParsedVariantQuery.java b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/ParsedVariantQuery.java index 586985a8d45..432ec90fb12 100644 --- a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/ParsedVariantQuery.java +++ b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/ParsedVariantQuery.java @@ -2,6 +2,7 @@ import org.opencb.biodata.models.core.Region; import org.opencb.biodata.models.variant.Variant; +import org.opencb.commons.datastore.core.Event; import org.opencb.commons.datastore.core.Query; import org.opencb.commons.datastore.core.QueryOptions; import org.opencb.opencga.storage.core.metadata.models.SampleMetadata; @@ -24,6 +25,8 @@ public class ParsedVariantQuery { private Query query; private boolean optimized = false; + private List events = new ArrayList<>(); + private VariantQueryProjection projection; private final VariantStudyQuery studyQuery; @@ -96,6 +99,15 @@ public ParsedVariantQuery setOptimized(boolean optimized) { return this; } + public List getEvents() { + return events; + } + + public ParsedVariantQuery setEvents(List events) { + this.events = events; + return this; + } + public VariantQueryProjection getProjection() { return projection; } diff --git a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/VariantQueryResult.java b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/VariantQueryResult.java index 79645987303..b1e6b13e8c5 100644 --- a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/VariantQueryResult.java +++ b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/VariantQueryResult.java @@ -24,6 +24,7 @@ import org.opencb.opencga.storage.core.variant.query.projection.VariantQueryProjection; import org.opencb.opencga.storage.core.variant.query.projection.VariantQueryProjectionParser; +import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -76,7 +77,7 @@ public VariantQueryResult(long time, int numResults, long numMatches, List) this, variantQuery); + addSamplesMetadataIfRequested(variantQuery); } } @@ -96,7 +97,7 @@ private VariantQueryResult(DataResult dataResult, List results) { public VariantQueryResult(DataResult dataResult, ParsedVariantQuery variantQuery) { this(dataResult, dataResult.getResults()); if (variantQuery != null) { - addSamplesMetadataIfRequested((VariantQueryResult) this, variantQuery); + addSamplesMetadataIfRequested(variantQuery); } } @@ -127,9 +128,22 @@ public VariantQueryResult(DataResult dataResult) { this(dataResult, (ParsedVariantQuery) null); } - private static VariantQueryResult addSamplesMetadataIfRequested(VariantQueryResult result, ParsedVariantQuery query) { + private void addSamplesMetadataIfRequested(ParsedVariantQuery query) { VariantQueryProjection projection = query.getProjection(); + if (!query.getEvents().isEmpty()) { + if (getEvents() == null) { + setEvents(new ArrayList<>()); + } + getEvents().addAll(query.getEvents()); + } + if (!projection.getEvents().isEmpty()) { + if (getEvents() == null) { + setEvents(new ArrayList<>()); + } + getEvents().addAll(projection.getEvents()); + } + int numTotalSamples = projection.getNumTotalSamples(); int numSamples = projection.getNumSamples(); if (query.getInputQuery().getBoolean(SAMPLE_METADATA.key(), false)) { @@ -139,15 +153,14 @@ private static VariantQueryResult addSamplesMetadataIfRequested(VariantQu VariantQueryProjectionParser.skipAndLimitSamples(query.getQuery(), samplesMetadata); numSamples = samplesMetadata.values().stream().mapToInt(List::size).sum(); } - return result.setNumSamples(numSamples) - .setNumTotalSamples(numTotalSamples) - .setSamples(samplesMetadata); + setNumSamples(numSamples); + setNumTotalSamples(numTotalSamples); + setSamples(samplesMetadata); } else { if (numTotalSamples >= 0 && numSamples >= 0) { - return result.setNumSamples(numSamples) - .setNumTotalSamples(numTotalSamples); + setNumSamples(numSamples); + setNumTotalSamples(numTotalSamples); } - return result; } } diff --git a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/projection/VariantQueryProjection.java b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/projection/VariantQueryProjection.java index 16b974ee57e..a31d810fffc 100644 --- a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/projection/VariantQueryProjection.java +++ b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/projection/VariantQueryProjection.java @@ -1,6 +1,7 @@ package org.opencb.opencga.storage.core.variant.query.projection; import com.google.common.collect.Iterables; +import org.opencb.commons.datastore.core.Event; import org.opencb.opencga.storage.core.metadata.models.StudyMetadata; import org.opencb.opencga.storage.core.variant.adaptors.VariantField; @@ -21,6 +22,7 @@ public final class VariantQueryProjection { private final int numSamples; private final int numTotalSamples; + private List events = new ArrayList<>(); public VariantQueryProjection(StudyMetadata studyMetadata, List samples, List files) { this.fields = VariantField.getIncludeFields(null); @@ -86,6 +88,15 @@ public Map> getFiles() { return studies.values().stream().collect(Collectors.toMap(s -> s.studyMetadata.getId(), s -> s.files)); } + public List getEvents() { + return events; + } + + public VariantQueryProjection setEvents(List events) { + this.events = events; + return this; + } + public static class StudyVariantQueryProjection { private StudyMetadata studyMetadata; private List samples = Collections.emptyList(); diff --git a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/projection/VariantQueryProjectionParser.java b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/projection/VariantQueryProjectionParser.java index 4ec7f2ec158..9c237a9493d 100644 --- a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/projection/VariantQueryProjectionParser.java +++ b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/projection/VariantQueryProjectionParser.java @@ -1,6 +1,7 @@ package org.opencb.opencga.storage.core.variant.query.projection; import org.apache.commons.collections4.CollectionUtils; +import org.opencb.commons.datastore.core.Event; import org.opencb.commons.datastore.core.Query; import org.opencb.commons.datastore.core.QueryOptions; import org.opencb.opencga.storage.core.metadata.VariantStorageMetadataManager; @@ -53,6 +54,7 @@ public static VariantQueryProjection parseVariantQueryFields( public VariantQueryProjection parseVariantQueryProjection(Query query, QueryOptions options) { Set includeFields = VariantField.getIncludeFields(options); + List events = new ArrayList<>(); List includeStudies = getIncludeStudies(query, options, metadataManager, includeFields); Map studies = new HashMap<>(includeStudies.size()); @@ -133,12 +135,16 @@ public VariantQueryProjection parseVariantQueryProjection(Query query, QueryOpti List cohorts = new LinkedList<>(); for (CohortMetadata cohort : metadataManager.getCalculatedOrInvalidCohorts(studyId)) { cohorts.add(cohort.getId()); + if (cohort.isInvalid()) { + events.add(new Event(Event.Type.WARNING, "Cohort '" + cohort.getName() + "' has outdated variant stats")); + } } study.setCohorts(cohorts); } } - return new VariantQueryProjection(includeFields, studies, numTotalSamples != numSamples, numSamples, numTotalSamples); + return new VariantQueryProjection(includeFields, studies, numTotalSamples != numSamples, numSamples, numTotalSamples) + .setEvents(events); } public static void skipAndLimitSamples(Query query, Map> sampleIds) { diff --git a/opencga-storage/opencga-storage-core/src/test/java/org/opencb/opencga/storage/core/variant/stats/VariantStatisticsManagerTest.java b/opencga-storage/opencga-storage-core/src/test/java/org/opencb/opencga/storage/core/variant/stats/VariantStatisticsManagerTest.java index 5fb147d6d9e..f9b0faa97f8 100644 --- a/opencga-storage/opencga-storage-core/src/test/java/org/opencb/opencga/storage/core/variant/stats/VariantStatisticsManagerTest.java +++ b/opencga-storage/opencga-storage-core/src/test/java/org/opencb/opencga/storage/core/variant/stats/VariantStatisticsManagerTest.java @@ -27,8 +27,8 @@ import org.opencb.biodata.tools.variant.VariantNormalizer; import org.opencb.biodata.tools.variant.stats.VariantStatsCalculator; import org.opencb.commons.datastore.core.ObjectMap; +import org.opencb.commons.datastore.core.Query; import org.opencb.commons.datastore.core.QueryOptions; -import org.opencb.opencga.core.api.ParamConstants; import org.opencb.opencga.storage.core.exceptions.StorageEngineException; import org.opencb.opencga.storage.core.metadata.models.CohortMetadata; import org.opencb.opencga.storage.core.metadata.models.SampleMetadata; @@ -39,6 +39,7 @@ import org.opencb.opencga.storage.core.variant.adaptors.VariantDBAdaptor; import org.opencb.opencga.storage.core.variant.adaptors.VariantQuery; import org.opencb.opencga.storage.core.variant.adaptors.iterators.VariantDBIterator; +import org.opencb.opencga.storage.core.variant.query.VariantQueryResult; import java.io.IOException; import java.net.URI; @@ -112,6 +113,42 @@ public void calculateStatsMultiCohortsTest() throws Exception { checkCohorts(dbAdaptor, studyMetadata); } + @Test + public void queryInvalidStats() throws Exception { + //Calculate stats for 2 cohorts at one time + checkCohorts(dbAdaptor, studyMetadata); + + QueryOptions options = new QueryOptions(); + options.put(VariantStorageOptions.LOAD_BATCH_SIZE.key(), 100); + Iterator iterator = metadataManager.sampleMetadataIterator(studyMetadata.getId()); + + /** Create cohorts **/ + HashSet cohort1 = new HashSet<>(); + cohort1.add(iterator.next().getName()); + cohort1.add(iterator.next().getName()); + + HashSet cohort2 = new HashSet<>(); + cohort2.add(iterator.next().getName()); + cohort2.add(iterator.next().getName()); + + Map> cohorts = new HashMap<>(); + cohorts.put("cohort1", cohort1); + cohorts.put("cohort2", cohort2); + + //Calculate stats + stats(options, studyMetadata.getName(), cohorts, outputUri.resolve("cohort1.cohort2.stats")); + + checkCohorts(dbAdaptor, studyMetadata); + + List cohort1Samples = metadataManager.getCohortMetadata(studyMetadata.getId(), "cohort1").getSamples(); + CohortMetadata cohort = metadataManager.addSamplesToCohort(studyMetadata.getId(), "cohort2", cohort1Samples); + assertTrue(cohort.isInvalid()); + + VariantQueryResult result = variantStorageEngine.get(new Query(), new QueryOptions(QueryOptions.LIMIT, 1)); + assertEquals(1, result.getEvents().size()); + assertEquals("Cohort 'cohort2' has outdated variant stats", result.getEvents().get(0).getMessage()); + } + @Test public void calculateStatsSeparatedCohortsTest() throws Exception { //Calculate stats for 2 cohorts separately From 789c35ff12b26137460df0ee6445be256bd0142f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacobo=20Coll=20Morag=C3=B3n?= Date: Wed, 17 Apr 2024 10:58:31 +0100 Subject: [PATCH 27/85] storage: Fix sampleSkip and sampleLimit. #TASK-5876 --- .../core/variant/adaptors/VariantQuery.java | 20 ++++--- .../variant/query/ParsedVariantQuery.java | 13 +++-- .../variant/query/VariantQueryParser.java | 56 +++++++++++-------- .../variant/query/VariantQueryResult.java | 36 ++++-------- .../VariantQueryProjectionParser.java | 9 +-- .../VariantDBAdaptorMultiFileTest.java | 10 ++-- .../variant/adaptors/VariantQueryTest.java | 6 ++ .../variant/HadoopVariantQueryParser.java | 5 +- .../variant/HadoopVariantStorageEngine.java | 5 +- .../adaptors/VariantHadoopDBAdaptor.java | 6 ++ 10 files changed, 88 insertions(+), 78 deletions(-) diff --git a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/adaptors/VariantQuery.java b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/adaptors/VariantQuery.java index 59f439897a5..9885536e2b3 100644 --- a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/adaptors/VariantQuery.java +++ b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/adaptors/VariantQuery.java @@ -216,20 +216,24 @@ public boolean includeGenotype() { return getBoolean(VariantQueryParam.INCLUDE_GENOTYPE.key()); } - public VariantQuery sampleLimit(String value) { + public VariantQuery sampleLimit(int value) { put(VariantQueryParam.SAMPLE_LIMIT.key(), value); return this; } - public String sampleLimit() { - return getString(VariantQueryParam.SAMPLE_LIMIT.key()); + public int sampleLimit() { + return getInt(VariantQueryParam.SAMPLE_LIMIT.key()); } public VariantQuery sampleSkip(String value) { put(VariantQueryParam.SAMPLE_SKIP.key(), value); return this; } - public String sampleSkip() { - return getString(VariantQueryParam.SAMPLE_SKIP.key()); + public VariantQuery sampleSkip(int value) { + put(VariantQueryParam.SAMPLE_SKIP.key(), value); + return this; + } + public int sampleSkip() { + return getInt(VariantQueryParam.SAMPLE_SKIP.key()); } public VariantQuery file(String value) { @@ -627,12 +631,12 @@ public VariantQuery release(String value) { put(VariantQueryParam.RELEASE.key(), value); return this; } - public VariantQuery release(int value) { + public VariantQuery release(Integer value) { put(VariantQueryParam.RELEASE.key(), value); return this; } - public String release() { - return getString(VariantQueryParam.RELEASE.key()); + public Integer release() { + return getInt(VariantQueryParam.RELEASE.key()); } @Override diff --git a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/ParsedVariantQuery.java b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/ParsedVariantQuery.java index 432ec90fb12..93e63e074d7 100644 --- a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/ParsedVariantQuery.java +++ b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/ParsedVariantQuery.java @@ -8,6 +8,7 @@ import org.opencb.opencga.storage.core.metadata.models.SampleMetadata; import org.opencb.opencga.storage.core.metadata.models.StudyMetadata; import org.opencb.opencga.storage.core.metadata.models.StudyResourceMetadata; +import org.opencb.opencga.storage.core.variant.adaptors.VariantQuery; import org.opencb.opencga.storage.core.variant.adaptors.VariantQueryException; import org.opencb.opencga.storage.core.variant.adaptors.VariantQueryParam; import org.opencb.opencga.storage.core.variant.query.projection.VariantQueryProjection; @@ -22,7 +23,7 @@ public class ParsedVariantQuery { private Query inputQuery; private QueryOptions inputOptions; - private Query query; + private VariantQuery query; private boolean optimized = false; private List events = new ArrayList<>(); @@ -44,21 +45,21 @@ public class ParsedVariantQuery { public ParsedVariantQuery() { this.inputQuery = new Query(); this.inputOptions = new QueryOptions(); - this.query = new Query(); + this.query = new VariantQuery(); studyQuery = new VariantStudyQuery(); } public ParsedVariantQuery(Query inputQuery, QueryOptions inputOptions) { this.inputQuery = inputQuery; this.inputOptions = inputOptions; - this.query = inputQuery; + this.query = new VariantQuery(inputQuery); studyQuery = new VariantStudyQuery(); } public ParsedVariantQuery(ParsedVariantQuery other) { this.inputQuery = new Query(other.inputQuery); this.inputOptions = new QueryOptions(other.inputOptions); - this.query = new Query(other.query); + this.query = new VariantQuery(other.query); this.projection = other.projection; this.studyQuery = new VariantStudyQuery(other.getStudyQuery()); this.optimized = other.optimized; @@ -81,11 +82,11 @@ public ParsedVariantQuery setInputQuery(Query inputQuery) { return this; } - public Query getQuery() { + public VariantQuery getQuery() { return query; } - public ParsedVariantQuery setQuery(Query query) { + public ParsedVariantQuery setQuery(VariantQuery query) { this.query = query; return this; } diff --git a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/VariantQueryParser.java b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/VariantQueryParser.java index aa07aaf3687..ec8b67faaa4 100644 --- a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/VariantQueryParser.java +++ b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/VariantQueryParser.java @@ -21,6 +21,7 @@ import org.opencb.opencga.storage.core.utils.CellBaseUtils; import org.opencb.opencga.storage.core.variant.VariantStorageOptions; import org.opencb.opencga.storage.core.variant.adaptors.GenotypeClass; +import org.opencb.opencga.storage.core.variant.adaptors.VariantQuery; import org.opencb.opencga.storage.core.variant.adaptors.VariantQueryException; import org.opencb.opencga.storage.core.variant.adaptors.VariantQueryParam; import org.opencb.opencga.storage.core.variant.query.projection.VariantQueryProjection; @@ -149,15 +150,15 @@ public ParsedVariantQuery parseQuery(Query query, QueryOptions options) { return parseQuery(query, options, false); } - public ParsedVariantQuery parseQuery(Query query, QueryOptions options, boolean skipPreProcess) { - if (query == null) { - query = new Query(); + public ParsedVariantQuery parseQuery(Query inputQuery, QueryOptions options, boolean skipPreProcess) { + if (inputQuery == null) { + inputQuery = new Query(); } if (options == null) { options = new QueryOptions(); } - ParsedVariantQuery variantQuery = new ParsedVariantQuery(new Query(query), new QueryOptions(options)); + ParsedVariantQuery variantQuery = new ParsedVariantQuery(new Query(inputQuery), new QueryOptions(options)); int limit = options.getInt(QueryOptions.LIMIT, -1); variantQuery.setLimit(limit == -1 ? null : limit); variantQuery.setSkip(options.getInt(QueryOptions.SKIP, 0)); @@ -166,15 +167,19 @@ public ParsedVariantQuery parseQuery(Query query, QueryOptions options, boolean VariantStorageOptions.APPROXIMATE_COUNT_SAMPLING_SIZE.key(), VariantStorageOptions.APPROXIMATE_COUNT_SAMPLING_SIZE.defaultValue())); + variantQuery.setProjection(projectionParser.parseVariantQueryProjection(inputQuery, options)); + + VariantQuery query; if (!skipPreProcess) { - query = preProcessQuery(query, options); + query = new VariantQuery(preProcessQuery(inputQuery, options, variantQuery.getProjection())); + } else { + query = new VariantQuery(inputQuery); } variantQuery.setQuery(query); - variantQuery.setProjection(projectionParser.parseVariantQueryProjection(query, options)); List geneRegions = Region.parseRegions(query.getString(ANNOT_GENE_REGIONS.key())); variantQuery.setGeneRegions(geneRegions == null ? Collections.emptyList() : geneRegions); - List regions = Region.parseRegions(query.getString(REGION.key()), true); + List regions = Region.parseRegions(query.region(), true); variantQuery.setRegions(regions == null ? Collections.emptyList() : regions); variantQuery.setClinicalCombination(VariantQueryParser.parseClinicalCombination(query, false)); variantQuery.setClinicalCombinationList(VariantQueryParser.parseClinicalCombinationsList(query, false)); @@ -188,7 +193,7 @@ public ParsedVariantQuery parseQuery(Query query, QueryOptions options, boolean } if (isValidParam(query, GENOTYPE)) { HashMap> map = new HashMap<>(); - QueryOperation op = VariantQueryUtils.parseGenotypeFilter(query.getString(GENOTYPE.key()), map); + QueryOperation op = VariantQueryUtils.parseGenotypeFilter(query.genotype(), map); if (defaultStudy == null) { List studyNames = metadataManager.getStudyNames(); @@ -224,13 +229,17 @@ public ParsedVariantQuery parseQuery(Query query, QueryOptions options, boolean return variantQuery; } - public Query preProcessQuery(Query originalQuery, QueryOptions options) { + public final Query preProcessQuery(Query originalQuery, QueryOptions options) { + return preProcessQuery(originalQuery, options, null); + } + + protected Query preProcessQuery(Query originalQuery, QueryOptions options, VariantQueryProjection projection) { // Copy input query! Do not modify original query! Query query = VariantQueryUtils.copy(originalQuery); preProcessAnnotationParams(query); - preProcessStudyParams(query, options); + preProcessStudyParams(query, options, projection); if (options != null && options.getLong(QueryOptions.LIMIT) < 0) { throw VariantQueryException.malformedParam(QueryOptions.LIMIT, options.getString(QueryOptions.LIMIT), @@ -376,7 +385,7 @@ private VariantType parseVariantType(String type) { } } - protected void preProcessStudyParams(Query query, QueryOptions options) { + protected void preProcessStudyParams(Query query, QueryOptions options, VariantQueryProjection projection) { StudyMetadata defaultStudy = getDefaultStudy(query); QueryOperation formatOperator = null; if (isValidParam(query, SAMPLE_DATA)) { @@ -676,22 +685,23 @@ protected void preProcessStudyParams(Query query, QueryOptions options) { if (!isValidParam(query, INCLUDE_STUDY) || !isValidParam(query, INCLUDE_SAMPLE) || !isValidParam(query, INCLUDE_FILE) - || !isValidParam(query, SAMPLE_SKIP) - || !isValidParam(query, SAMPLE_LIMIT) + || isValidParam(query, SAMPLE_SKIP) + || isValidParam(query, SAMPLE_LIMIT) ) { - VariantQueryProjection selectVariantElements = - VariantQueryProjectionParser.parseVariantQueryFields(query, options, metadataManager); + if (projection == null) { + projection = projectionParser.parseVariantQueryProjection(query, options); + } // Apply the sample pagination. // Remove the sampleLimit and sampleSkip to avoid applying the pagination twice query.remove(SAMPLE_SKIP.key()); query.remove(SAMPLE_LIMIT.key()); - query.put(NUM_TOTAL_SAMPLES.key(), selectVariantElements.getNumTotalSamples()); - query.put(NUM_SAMPLES.key(), selectVariantElements.getNumSamples()); + query.put(NUM_TOTAL_SAMPLES.key(), projection.getNumTotalSamples()); + query.put(NUM_SAMPLES.key(), projection.getNumSamples()); if (!isValidParam(query, INCLUDE_STUDY)) { List includeStudy = new ArrayList<>(); - for (Integer studyId : selectVariantElements.getStudyIds()) { - includeStudy.add(selectVariantElements.getStudy(studyId).getStudyMetadata().getName()); + for (Integer studyId : projection.getStudyIds()) { + includeStudy.add(projection.getStudy(studyId).getStudyMetadata().getName()); } if (includeStudy.isEmpty()) { query.put(INCLUDE_STUDY.key(), NONE); @@ -699,8 +709,8 @@ protected void preProcessStudyParams(Query query, QueryOptions options) { query.put(INCLUDE_STUDY.key(), includeStudy); } } - if (!isValidParam(query, INCLUDE_SAMPLE) || selectVariantElements.getSamplePagination()) { - List includeSample = selectVariantElements.getSampleNames().values() + if (!isValidParam(query, INCLUDE_SAMPLE) || projection.getSamplePagination()) { + List includeSample = projection.getSampleNames().values() .stream().flatMap(Collection::stream).collect(Collectors.toList()); if (includeSample.isEmpty()) { query.put(INCLUDE_SAMPLE.key(), NONE); @@ -708,8 +718,8 @@ protected void preProcessStudyParams(Query query, QueryOptions options) { query.put(INCLUDE_SAMPLE.key(), includeSample); } } - if (!isValidParam(query, INCLUDE_FILE) || selectVariantElements.getSamplePagination()) { - List includeFile = selectVariantElements.getFiles() + if (!isValidParam(query, INCLUDE_FILE) || projection.getSamplePagination()) { + List includeFile = projection.getFiles() .entrySet() .stream() .flatMap(e -> e.getValue() diff --git a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/VariantQueryResult.java b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/VariantQueryResult.java index b1e6b13e8c5..f72cdf10058 100644 --- a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/VariantQueryResult.java +++ b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/VariantQueryResult.java @@ -22,14 +22,11 @@ import org.opencb.commons.datastore.core.ObjectMap; import org.opencb.opencga.core.response.OpenCGAResult; import org.opencb.opencga.storage.core.variant.query.projection.VariantQueryProjection; -import org.opencb.opencga.storage.core.variant.query.projection.VariantQueryProjectionParser; import java.util.ArrayList; import java.util.List; import java.util.Map; -import static org.opencb.opencga.storage.core.variant.adaptors.VariantQueryParam.SAMPLE_METADATA; - /** * Created on 07/02/17. * @@ -76,6 +73,9 @@ public VariantQueryResult(long time, int numResults, long numMatches, List()); + } if (variantQuery != null) { addSamplesMetadataIfRequested(variantQuery); } @@ -92,6 +92,9 @@ private VariantQueryResult(DataResult dataResult, List results) { dataResult.getAttributes()); setResults(results); setNumResults(results.size()); + if (getEvents() == null) { + setEvents(new ArrayList<>()); + } } public VariantQueryResult(DataResult dataResult, ParsedVariantQuery variantQuery) { @@ -132,36 +135,17 @@ private void addSamplesMetadataIfRequested(ParsedVariantQuery query) { VariantQueryProjection projection = query.getProjection(); if (!query.getEvents().isEmpty()) { - if (getEvents() == null) { - setEvents(new ArrayList<>()); - } getEvents().addAll(query.getEvents()); } if (!projection.getEvents().isEmpty()) { - if (getEvents() == null) { - setEvents(new ArrayList<>()); - } getEvents().addAll(projection.getEvents()); } - int numTotalSamples = projection.getNumTotalSamples(); - int numSamples = projection.getNumSamples(); - if (query.getInputQuery().getBoolean(SAMPLE_METADATA.key(), false)) { - Map> samplesMetadata = query.getProjection().getSampleNames(); - if (numTotalSamples < 0 && numSamples < 0) { - numTotalSamples = samplesMetadata.values().stream().mapToInt(List::size).sum(); - VariantQueryProjectionParser.skipAndLimitSamples(query.getQuery(), samplesMetadata); - numSamples = samplesMetadata.values().stream().mapToInt(List::size).sum(); - } - setNumSamples(numSamples); - setNumTotalSamples(numTotalSamples); - setSamples(samplesMetadata); - } else { - if (numTotalSamples >= 0 && numSamples >= 0) { - setNumSamples(numSamples); - setNumTotalSamples(numTotalSamples); - } + if (query.getQuery().sampleMetadata()) { + setSamples(query.getProjection().getSampleNames()); } + setNumSamples(projection.getNumSamples()); + setNumTotalSamples(projection.getNumTotalSamples()); } public Map> getSamples() { diff --git a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/projection/VariantQueryProjectionParser.java b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/projection/VariantQueryProjectionParser.java index 9c237a9493d..138d833e465 100644 --- a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/projection/VariantQueryProjectionParser.java +++ b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/projection/VariantQueryProjectionParser.java @@ -70,6 +70,10 @@ public VariantQueryProjection parseVariantQueryProjection(Query query, QueryOpti } Map> sampleIdsMap = getIncludeSampleIds(query, options, includeStudies, metadataManager); + int numTotalSamples = sampleIdsMap.values().stream().mapToInt(List::size).sum(); + skipAndLimitSamples(query, sampleIdsMap); + int numSamples = sampleIdsMap.values().stream().mapToInt(List::size).sum(); + for (VariantQueryProjection.StudyVariantQueryProjection study : studies.values()) { List sampleIds = sampleIdsMap.get(study.getId()); study.setSamples(sampleIds); @@ -79,9 +83,6 @@ public VariantQueryProjection parseVariantQueryProjection(Query query, QueryOpti } study.setSampleNames(sampleNames); } - int numTotalSamples = sampleIdsMap.values().stream().mapToInt(List::size).sum(); - skipAndLimitSamples(query, sampleIdsMap); - int numSamples = sampleIdsMap.values().stream().mapToInt(List::size).sum(); Map> fileIdsMap = getIncludeFiles(query, includeStudies, includeFields, metadataManager, sampleIdsMap); @@ -147,7 +148,7 @@ public VariantQueryProjection parseVariantQueryProjection(Query query, QueryOpti .setEvents(events); } - public static void skipAndLimitSamples(Query query, Map> sampleIds) { + private void skipAndLimitSamples(Query query, Map> sampleIds) { if (VariantQueryUtils.isValidParam(query, VariantQueryParam.SAMPLE_SKIP)) { int skip = query.getInt(VariantQueryParam.SAMPLE_SKIP.key()); if (skip > 0) { diff --git a/opencga-storage/opencga-storage-core/src/test/java/org/opencb/opencga/storage/core/variant/adaptors/VariantDBAdaptorMultiFileTest.java b/opencga-storage/opencga-storage-core/src/test/java/org/opencb/opencga/storage/core/variant/adaptors/VariantDBAdaptorMultiFileTest.java index f52790a19c1..2a1d859ea7b 100644 --- a/opencga-storage/opencga-storage-core/src/test/java/org/opencb/opencga/storage/core/variant/adaptors/VariantDBAdaptorMultiFileTest.java +++ b/opencga-storage/opencga-storage-core/src/test/java/org/opencb/opencga/storage/core/variant/adaptors/VariantDBAdaptorMultiFileTest.java @@ -10,6 +10,7 @@ import org.opencb.biodata.models.variant.avro.SampleEntry; import org.opencb.biodata.models.variant.stats.VariantStats; import org.opencb.commons.datastore.core.*; +import org.opencb.opencga.storage.core.variant.query.ParsedVariantQuery; import org.opencb.opencga.storage.core.variant.query.VariantQueryResult; import org.opencb.opencga.storage.core.exceptions.StorageEngineException; import org.opencb.opencga.storage.core.metadata.VariantStorageMetadataManager; @@ -111,9 +112,8 @@ protected void load() throws Exception { } protected VariantQueryResult query(Query query, QueryOptions options) { - options = options == null ? QueryOptions.empty() : options; - query = variantStorageEngine.preProcessQuery(query, options); - return dbAdaptor.get(query, options); + ParsedVariantQuery variantQuery = variantStorageEngine.parseQuery(query, options); + return dbAdaptor.get(variantQuery); } protected ObjectMap getOptions() { @@ -382,13 +382,13 @@ public void testSampleLimitSkip() throws Exception { System.out.println("samples(ALL) = " + result.getSamples()); for (int i : new int[]{1, 3, 6, 8, 10}) { - result = query(new Query(VariantQueryParam.SAMPLE_SKIP.key(), i).append(VariantQueryParam.INCLUDE_SAMPLE.key(), ALL).append(SAMPLE_METADATA.key(), true), options); + result = query(new VariantQuery().sampleSkip(i).includeSampleAll().sampleMetadata(true), options); // System.out.println("samples(SKIP=" + i + ") = " + result.getSamples()); assertEquals(Math.max(0, 8 - i), result.getSamples().values().stream().mapToInt(List::size).sum()); assertEquals(Math.max(0, 8 - i), result.getNumSamples().intValue()); assertEquals(8, result.getNumTotalSamples().intValue()); - result = query(new Query(VariantQueryParam.SAMPLE_LIMIT.key(), i).append(VariantQueryParam.INCLUDE_SAMPLE.key(), ALL).append(SAMPLE_METADATA.key(), true), options); + result = query(new VariantQuery().sampleLimit(i).includeSampleAll().sampleMetadata(true), options); // System.out.println("samples(LIMIT=" + i + ") = " + result.getSamples()); assertEquals(Math.min(8, i), result.getSamples().values().stream().mapToInt(List::size).sum()); assertEquals(Math.min(8, i), result.getNumSamples().intValue()); diff --git a/opencga-storage/opencga-storage-core/src/test/java/org/opencb/opencga/storage/core/variant/adaptors/VariantQueryTest.java b/opencga-storage/opencga-storage-core/src/test/java/org/opencb/opencga/storage/core/variant/adaptors/VariantQueryTest.java index de17c52a8a0..5cfdde4ca13 100644 --- a/opencga-storage/opencga-storage-core/src/test/java/org/opencb/opencga/storage/core/variant/adaptors/VariantQueryTest.java +++ b/opencga-storage/opencga-storage-core/src/test/java/org/opencb/opencga/storage/core/variant/adaptors/VariantQueryTest.java @@ -28,6 +28,12 @@ public void test() throws Exception { if (param.type() == QueryParam.Type.BOOLEAN || param.type() == QueryParam.Type.BOOLEAN_ARRAY) { methodSet = getMethodSafe(param.key(), boolean.class); expectedValue = true; + } else if (param.type() == QueryParam.Type.INTEGER || param.type() == QueryParam.Type.INTEGER_ARRAY) { + methodSet = getMethodSafe(param.key(), int.class); + expectedValue = 42; + if (methodSet == null) { + methodSet = getMethodSafe(param.key(), Integer.class); + } } else { expectedValue = RandomStringUtils.random(10); methodSet = getMethodSafe(param.key(), String.class); diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/HadoopVariantQueryParser.java b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/HadoopVariantQueryParser.java index 45682df31f4..6aa472ee735 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/HadoopVariantQueryParser.java +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/HadoopVariantQueryParser.java @@ -5,6 +5,7 @@ import org.opencb.opencga.storage.core.metadata.VariantStorageMetadataManager; import org.opencb.opencga.storage.core.utils.CellBaseUtils; import org.opencb.opencga.storage.core.variant.query.VariantQueryParser; +import org.opencb.opencga.storage.core.variant.query.projection.VariantQueryProjection; import java.util.List; @@ -17,8 +18,8 @@ public HadoopVariantQueryParser(CellBaseUtils cellBaseUtils, VariantStorageMetad } @Override - public Query preProcessQuery(Query originalQuery, QueryOptions options) { - Query query = super.preProcessQuery(originalQuery, options); + protected Query preProcessQuery(Query originalQuery, QueryOptions options, VariantQueryProjection projection) { + Query query = super.preProcessQuery(originalQuery, options, projection); List studyNames = metadataManager.getStudyNames(); if (isValidParam(query, STUDY) && studyNames.size() == 1) { diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/HadoopVariantStorageEngine.java b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/HadoopVariantStorageEngine.java index 8052ac5622c..d56798f0de9 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/HadoopVariantStorageEngine.java +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/HadoopVariantStorageEngine.java @@ -1029,10 +1029,7 @@ private synchronized HBaseManager getHBaseManager(Configuration configuration) { @Override public ParsedVariantQuery parseQuery(Query originalQuery, QueryOptions options) { try { - Query query = preProcessQuery(originalQuery, options); - ParsedVariantQuery parsedVariantQuery = getVariantQueryParser().parseQuery(query, options, true); - parsedVariantQuery.setInputQuery(originalQuery); - return parsedVariantQuery; + return getVariantQueryParser().parseQuery(originalQuery, options); } catch (StorageEngineException e) { throw VariantQueryException.internalException(e).setQuery(originalQuery); } diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/adaptors/VariantHadoopDBAdaptor.java b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/adaptors/VariantHadoopDBAdaptor.java index 38b4d9c1718..d3c608c8b42 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/adaptors/VariantHadoopDBAdaptor.java +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/adaptors/VariantHadoopDBAdaptor.java @@ -247,6 +247,12 @@ public VariantQueryResult get(ParsedVariantQuery query) { .setConvertTime(iterator.getTimeConverting(TimeUnit.MILLISECONDS)); } + @Override + @Deprecated + public VariantQueryResult get(Query query, QueryOptions options) { + return get(new HadoopVariantQueryParser(null, getMetadataManager()).parseQuery(query, options)); + } + @Override public VariantQueryResult getPhased(String variant, String studyName, String sampleName, QueryOptions options, int windowsSize) { From bde39d3e92dbde10a0706ee08b5621d4ef4cca2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacobo=20Coll=20Morag=C3=B3n?= Date: Wed, 17 Apr 2024 13:46:37 +0100 Subject: [PATCH 28/85] storage: Fix error querying samples with deleted files. #TASK-5876 --- .../phoenix/VariantSqlQueryParser.java | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/adaptors/phoenix/VariantSqlQueryParser.java b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/adaptors/phoenix/VariantSqlQueryParser.java index 2d5c66b6dd9..7750583e0b8 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/adaptors/phoenix/VariantSqlQueryParser.java +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/adaptors/phoenix/VariantSqlQueryParser.java @@ -125,8 +125,6 @@ public String parse(Query query, QueryOptions options) { public String parse(ParsedVariantQuery variantQuery, QueryOptions options) { Query query = variantQuery.getQuery(); - StringBuilder sb = new StringBuilder("SELECT "); - try { Set dynamicColumns = new HashSet<>(); @@ -145,21 +143,22 @@ public String parse(ParsedVariantQuery variantQuery, QueryOptions options) { hints.add(HintNode.Hint.valueOf(hint)); } } + + StringBuilder sb = new StringBuilder("SELECT "); if (!hints.isEmpty()) { sb.append("/*+ ").append(hints.stream().map(Object::toString).collect(Collectors.joining(","))).append(" */ "); } - appendProjectedColumns(sb, variantQuery.getProjection(), options); appendFromStatement(sb, dynamicColumns); appendWhereStatement(sb, regionFilters, filters); appendOrderby(options, sb); appendLimitSkip(options, sb); + return sb.toString(); } catch (VariantQueryException e) { e.setQuery(query); throw e; } - return sb.toString(); } private void appendOrderby(QueryOptions options, StringBuilder sb) { @@ -217,7 +216,6 @@ protected StringBuilder appendProjectedColumns(StringBuilder sb, VariantQueryPro return sb.append(" COUNT(*) "); } else { Set returnedFields = projection.getFields(); - Collection studyIds = projection.getStudyIds(); sb.append(VariantColumn.CHROMOSOME).append(',') .append(VariantColumn.POSITION).append(',') @@ -967,36 +965,38 @@ protected void addVariantFilters(ParsedVariantQuery variantQuery, QueryOptions o } boolean multiFileSample = VariantStorageEngine.SplitData.MULTI.equals(sampleMetadata.getSplitData()); List sampleFiles = new ArrayList<>(); + // First file does not have the fileID in the column name + Integer firstSampleFile = sampleMetadata.getFiles().get(0); + if (multiFileSample) { if (fileIds.isEmpty()) { - sampleFiles.add(null); // First file does not have the fileID in the column name List fileIdsFromSampleId = sampleMetadata.getFiles(); - sampleFiles.addAll(fileIdsFromSampleId.subList(1, fileIdsFromSampleId.size())); + sampleFiles.addAll(fileIdsFromSampleId); } else { for (Pair fileIdPair : fileIds) { if (fileIdPair.getKey().equals(studyId)) { - Integer fileId = fileIdPair.getValue(); - int idx = sampleMetadata.getFiles().indexOf(fileId); - if (idx == 0) { - sampleFiles.add(null); // First file does not have the fileID in the column name - } else if (idx > 0) { - sampleFiles.add(fileId); // First file does not have the fileID in the column name - } + sampleFiles.add(fileIdPair.getValue()); } } } } else { - sampleFiles.add(null); // First file does not have the fileID in the column name + // Non multi file sample + sampleFiles.add(firstSampleFile); } for (Integer sampleFile : sampleFiles) { + if (!metadataManager.isFileIndexed(studyId, sampleFile)) { + // Skip non indexed files + continue; + } List sampleFileGtFilters = new ArrayList<>(genotypes.size()); for (String genotype : genotypes) { if (negated) { genotype = removeNegation(genotype); } String key; - if (sampleFile == null) { + if (Objects.equals(sampleFile, firstSampleFile)) { + // Special scenario for the first file. Column name does not contain the fileId key = buildSampleColumnKey(studyId, sampleId, new StringBuilder()).toString(); } else { key = buildSampleColumnKey(studyId, sampleId, sampleFile, new StringBuilder()).toString(); From ab3c55ececa35cbff5a9e3ab6043f612faf8dc67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacobo=20Coll=20Morag=C3=B3n?= Date: Thu, 18 Apr 2024 10:47:21 +0100 Subject: [PATCH 29/85] storage: Fix exception modifying an emptyList() #TASK-5876 --- .../storage/core/variant/query/VariantQueryResult.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/VariantQueryResult.java b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/VariantQueryResult.java index f72cdf10058..ee432deb3b7 100644 --- a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/VariantQueryResult.java +++ b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/VariantQueryResult.java @@ -24,6 +24,7 @@ import org.opencb.opencga.storage.core.variant.query.projection.VariantQueryProjection; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.Map; @@ -134,6 +135,10 @@ public VariantQueryResult(DataResult dataResult) { private void addSamplesMetadataIfRequested(ParsedVariantQuery query) { VariantQueryProjection projection = query.getProjection(); + // Ensure is modifiable + if (getEvents() == null || Collections.emptyList().getClass().equals(getEvents().getClass())) { + setEvents(new ArrayList<>()); + } if (!query.getEvents().isEmpty()) { getEvents().addAll(query.getEvents()); } From b10b5c7a33c35190adcd9c7fc0345e7c9cd50f86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacobo=20Coll=20Morag=C3=B3n?= Date: Thu, 18 Apr 2024 11:21:33 +0100 Subject: [PATCH 30/85] storage: Improve warning event. Add cohort samples diff. #TASK-5876 --- .../core/metadata/VariantStorageMetadataManager.java | 1 + .../storage/core/metadata/models/CohortMetadata.java | 1 + .../query/projection/VariantQueryProjectionParser.java | 9 ++++++++- 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/metadata/VariantStorageMetadataManager.java b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/metadata/VariantStorageMetadataManager.java index ce037e948dc..65812bd7017 100644 --- a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/metadata/VariantStorageMetadataManager.java +++ b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/metadata/VariantStorageMetadataManager.java @@ -1249,6 +1249,7 @@ private CohortMetadata updateCohortSamples(int studyId, String cohortName, Colle if (!oldSamples.equals(sampleIdsList) || !oldFiles.equals(fileIds)) { // Cohort has been modified! Invalidate stats cohort.setStatsStatus(TaskMetadata.Status.ERROR); + cohort.getAttributes().put(CohortMetadata.INVALID_STATS_NUM_SAMPLES, oldSamples.size()); } } } diff --git a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/metadata/models/CohortMetadata.java b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/metadata/models/CohortMetadata.java index 4814fc82b63..a4e9de4116e 100644 --- a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/metadata/models/CohortMetadata.java +++ b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/metadata/models/CohortMetadata.java @@ -8,6 +8,7 @@ * @author Jacobo Coll <jacobo167@gmail.com> */ public class CohortMetadata extends StudyResourceMetadata { + public static final String INVALID_STATS_NUM_SAMPLES = "invalidStatsNumSamples"; // private int studyId; // private int id; diff --git a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/projection/VariantQueryProjectionParser.java b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/projection/VariantQueryProjectionParser.java index 138d833e465..90fe6464641 100644 --- a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/projection/VariantQueryProjectionParser.java +++ b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/projection/VariantQueryProjectionParser.java @@ -137,7 +137,14 @@ public VariantQueryProjection parseVariantQueryProjection(Query query, QueryOpti for (CohortMetadata cohort : metadataManager.getCalculatedOrInvalidCohorts(studyId)) { cohorts.add(cohort.getId()); if (cohort.isInvalid()) { - events.add(new Event(Event.Type.WARNING, "Cohort '" + cohort.getName() + "' has outdated variant stats")); + String message = "Cohort '" + cohort.getName() + "' has outdated variant stats."; + int numSampmles = cohort.getSamples().size(); + int invalidStatsNumSamples = cohort.getAttributes().getInt(CohortMetadata.INVALID_STATS_NUM_SAMPLES, -1); + if (invalidStatsNumSamples > 0) { + message += " Existing stats are calculated with " + invalidStatsNumSamples + " samples, " + + "but the cohort currently has " + numSampmles + " samples."; + } + events.add(new Event(Event.Type.WARNING, message)); } } study.setCohorts(cohorts); From 4d20481e9e6976db8432bb8e059cc8860d0bc14f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacobo=20Coll=20Morag=C3=B3n?= Date: Thu, 18 Apr 2024 14:20:59 +0100 Subject: [PATCH 31/85] storage: Fix wrong columns at sample+file sql query build. #TASK-5876 --- .../core/variant/query/VariantQueryUtils.java | 7 ++++ .../VariantQueryProjectionParser.java | 8 ++-- .../stats/VariantStatisticsManagerTest.java | 4 +- .../phoenix/VariantSqlQueryParser.java | 40 +++++++++---------- .../variant/index/sample/SampleIndexTest.java | 4 +- 5 files changed, 37 insertions(+), 26 deletions(-) diff --git a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/VariantQueryUtils.java b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/VariantQueryUtils.java index b4e2e7819d3..f8c361be415 100644 --- a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/VariantQueryUtils.java +++ b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/VariantQueryUtils.java @@ -1542,6 +1542,13 @@ public static String printQuery(Query query) { query.put(ANNOT_GENE_REGIONS.key(), "numGeneRegions : " + ((Collection) geneRegions).size()); } } + if (isValidParam(query, ID_INTERSECT)) { + query = new Query(query); + Object idIntersect = query.get(ID_INTERSECT.key()); + if (idIntersect instanceof Collection) { + query.put(ID_INTERSECT.key(), "numIdIntersect : " + ((Collection) idIntersect).size()); + } + } try { return QUERY_MAPPER.writeValueAsString(query); } catch (JsonProcessingException e) { diff --git a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/projection/VariantQueryProjectionParser.java b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/projection/VariantQueryProjectionParser.java index 90fe6464641..3ec0c32c08a 100644 --- a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/projection/VariantQueryProjectionParser.java +++ b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/projection/VariantQueryProjectionParser.java @@ -137,13 +137,15 @@ public VariantQueryProjection parseVariantQueryProjection(Query query, QueryOpti for (CohortMetadata cohort : metadataManager.getCalculatedOrInvalidCohorts(studyId)) { cohorts.add(cohort.getId()); if (cohort.isInvalid()) { - String message = "Cohort '" + cohort.getName() + "' has outdated variant stats."; + String message = "Please note that the Cohort Stats for " + + "'" + study.getName() + ":" + cohort.getName() + "' are currently outdated."; int numSampmles = cohort.getSamples().size(); int invalidStatsNumSamples = cohort.getAttributes().getInt(CohortMetadata.INVALID_STATS_NUM_SAMPLES, -1); if (invalidStatsNumSamples > 0) { - message += " Existing stats are calculated with " + invalidStatsNumSamples + " samples, " - + "but the cohort currently has " + numSampmles + " samples."; + message += " The statistics have been calculated with " + invalidStatsNumSamples + " samples, " + + "while the total number of samples in the cohort is " + numSampmles + "."; } + message += " To display updated statistics, please execute variant-stats-index."; events.add(new Event(Event.Type.WARNING, message)); } } diff --git a/opencga-storage/opencga-storage-core/src/test/java/org/opencb/opencga/storage/core/variant/stats/VariantStatisticsManagerTest.java b/opencga-storage/opencga-storage-core/src/test/java/org/opencb/opencga/storage/core/variant/stats/VariantStatisticsManagerTest.java index f9b0faa97f8..baafe7d0ad6 100644 --- a/opencga-storage/opencga-storage-core/src/test/java/org/opencb/opencga/storage/core/variant/stats/VariantStatisticsManagerTest.java +++ b/opencga-storage/opencga-storage-core/src/test/java/org/opencb/opencga/storage/core/variant/stats/VariantStatisticsManagerTest.java @@ -146,7 +146,9 @@ public void queryInvalidStats() throws Exception { VariantQueryResult result = variantStorageEngine.get(new Query(), new QueryOptions(QueryOptions.LIMIT, 1)); assertEquals(1, result.getEvents().size()); - assertEquals("Cohort 'cohort2' has outdated variant stats", result.getEvents().get(0).getMessage()); + assertEquals("Please note that the Cohort Stats for '1000g:cohort2' are currently outdated." + + " The statistics have been calculated with 2 samples, while the total number of samples in the cohort is 4." + + " To display updated statistics, please execute variant-stats-index.", result.getEvents().get(0).getMessage()); } @Test diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/adaptors/phoenix/VariantSqlQueryParser.java b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/adaptors/phoenix/VariantSqlQueryParser.java index 7750583e0b8..7cc9dd77bf4 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/adaptors/phoenix/VariantSqlQueryParser.java +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/adaptors/phoenix/VariantSqlQueryParser.java @@ -974,7 +974,8 @@ protected void addVariantFilters(ParsedVariantQuery variantQuery, QueryOptions o sampleFiles.addAll(fileIdsFromSampleId); } else { for (Pair fileIdPair : fileIds) { - if (fileIdPair.getKey().equals(studyId)) { + if (fileIdPair.getKey().equals(studyId) + && sampleMetadata.getFiles().contains(fileIdPair.getValue())) { sampleFiles.add(fileIdPair.getValue()); } } @@ -1231,27 +1232,24 @@ private void addSampleDataFilter(ParsedVariantQuery query, List filters, SampleMetadata sampleMetadata = sampleDataFilter.getKey(); boolean multiFileSample = VariantStorageEngine.SplitData.MULTI.equals(sampleMetadata.getSplitData()); + // First file does not have the fileID in the column name + Integer firstSampleFile = sampleMetadata.getFiles().get(0); List sampleFiles = new ArrayList<>(); if (multiFileSample) { if (fileIds.isEmpty()) { - sampleFiles.add(null); // First file does not have the fileID in the column name List fileIdsFromSampleId = sampleMetadata.getFiles(); - sampleFiles.addAll(fileIdsFromSampleId.subList(1, fileIdsFromSampleId.size())); + sampleFiles.addAll(fileIdsFromSampleId); } else { for (Pair fileIdPair : fileIds) { - if (fileIdPair.getKey().equals(sampleMetadata.getStudyId())) { - Integer fileId = fileIdPair.getValue(); - int idx = sampleMetadata.getFiles().indexOf(fileId); - if (idx == 0) { - sampleFiles.add(null); // First file does not have the fileID in the column name - } else if (idx > 0) { - sampleFiles.add(fileId); // First file does not have the fileID in the column name - } + if (fileIdPair.getKey().equals(sampleMetadata.getStudyId()) + && sampleMetadata.getFiles().contains(fileIdPair.getValue())) { + sampleFiles.add(fileIdPair.getValue()); } } } } else { - sampleFiles.add(null); // First file does not have the fileID in the column name + // Non multi file sample + sampleFiles.add(firstSampleFile); } for (Integer sampleFile : sampleFiles) { List sampleFileFilters = new LinkedList<>(); @@ -1271,10 +1269,11 @@ private void addSampleDataFilter(ParsedVariantQuery query, List filters, sb.append("TO_NUMBER("); } sb.append('"'); - if (sampleFile != null) { - buildSampleColumnKey(sampleMetadata.getStudyId(), sampleMetadata.getId(), sampleFile, sb); - } else { + if (Objects.equals(sampleFile, firstSampleFile)) { + // Special scenario for the first file. Column name does not contain the fileId buildSampleColumnKey(sampleMetadata.getStudyId(), sampleMetadata.getId(), sb); + } else { + buildSampleColumnKey(sampleMetadata.getStudyId(), sampleMetadata.getId(), sampleFile, sb); } sb.append('"'); @@ -1288,10 +1287,11 @@ private void addSampleDataFilter(ParsedVariantQuery query, List filters, if (op.startsWith(">>") || op.startsWith("<<")) { sb.append(" OR \""); - if (sampleFile != null) { - buildSampleColumnKey(sampleMetadata.getStudyId(), sampleMetadata.getId(), sampleFile, sb); - } else { + if (Objects.equals(sampleFile, firstSampleFile)) { + // Special scenario for the first file. Column name does not contain the fileId buildSampleColumnKey(sampleMetadata.getStudyId(), sampleMetadata.getId(), sb); + } else { + buildSampleColumnKey(sampleMetadata.getStudyId(), sampleMetadata.getId(), sampleFile, sb); } sb.append('"'); @@ -1308,8 +1308,8 @@ private void addSampleDataFilter(ParsedVariantQuery query, List filters, if (multiFileSample) { // The first file is null. Get the actual fileId Integer actualFileId; - if (sampleFile == null) { - actualFileId = sampleMetadata.getFiles().get(0); + if (Objects.equals(sampleFile, firstSampleFile)) { + actualFileId = firstSampleFile; } else { actualFileId = sampleFile; } diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/test/java/org/opencb/opencga/storage/hadoop/variant/index/sample/SampleIndexTest.java b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/test/java/org/opencb/opencga/storage/hadoop/variant/index/sample/SampleIndexTest.java index 1ee4944733e..e15cb6ae4bb 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/test/java/org/opencb/opencga/storage/hadoop/variant/index/sample/SampleIndexTest.java +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/test/java/org/opencb/opencga/storage/hadoop/variant/index/sample/SampleIndexTest.java @@ -369,8 +369,8 @@ public void regenerateSampleIndex() throws Exception { } public VariantQueryResult dbAdaptorQuery(Query query, QueryOptions options) { - query = variantStorageEngine.preProcessQuery(query, options); - return dbAdaptor.get(query, options); + ParsedVariantQuery variantQuery = variantStorageEngine.parseQuery(query, options); + return dbAdaptor.get(variantQuery); } @Test From 74851ede86c0cff18ea6ed86cdeffc9e7e5a8a9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joaqu=C3=ADn=20T=C3=A1rraga=20Gim=C3=A9nez?= Date: Tue, 23 Apr 2024 17:33:06 +0200 Subject: [PATCH 32/85] analysis: include the folder src/test/resources in the testResources section of the pom.xml file, #TASK-6082 --- opencga-analysis/pom.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/opencga-analysis/pom.xml b/opencga-analysis/pom.xml index abd6d563378..4958a137880 100644 --- a/opencga-analysis/pom.xml +++ b/opencga-analysis/pom.xml @@ -250,6 +250,9 @@ log4j2-test.xml + + src/test/resources + From 212c472654c129751b5f5ed9b154b8d4a97dc6d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacobo=20Coll=20Morag=C3=B3n?= Date: Wed, 24 Apr 2024 14:42:31 +0100 Subject: [PATCH 33/85] storage: Fix test after merge #TASK-5876 --- .../variant/query/executors/VariantQueryExecutorTest.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/opencga-storage/opencga-storage-core/src/test/java/org/opencb/opencga/storage/core/variant/query/executors/VariantQueryExecutorTest.java b/opencga-storage/opencga-storage-core/src/test/java/org/opencb/opencga/storage/core/variant/query/executors/VariantQueryExecutorTest.java index b5fdde0fb85..c58328d4469 100644 --- a/opencga-storage/opencga-storage-core/src/test/java/org/opencb/opencga/storage/core/variant/query/executors/VariantQueryExecutorTest.java +++ b/opencga-storage/opencga-storage-core/src/test/java/org/opencb/opencga/storage/core/variant/query/executors/VariantQueryExecutorTest.java @@ -8,7 +8,6 @@ import org.opencb.commons.datastore.core.ObjectMap; import org.opencb.commons.datastore.core.Query; import org.opencb.commons.datastore.core.QueryOptions; -import org.opencb.opencga.core.response.VariantQueryResult; import org.opencb.opencga.storage.core.StoragePipelineResult; import org.opencb.opencga.storage.core.exceptions.StorageEngineException; import org.opencb.opencga.storage.core.metadata.VariantStorageMetadataManager; @@ -20,6 +19,7 @@ import org.opencb.opencga.storage.core.variant.adaptors.VariantQuery; import org.opencb.opencga.storage.core.variant.adaptors.VariantQueryParam; import org.opencb.opencga.storage.core.variant.query.ParsedVariantQuery; +import org.opencb.opencga.storage.core.variant.query.VariantQueryResult; import org.opencb.opencga.storage.core.variant.query.VariantQueryUtils; import org.opencb.opencga.storage.core.variant.query.projection.VariantQueryProjection; import org.opencb.opencga.storage.core.variant.solr.VariantSolrExternalResource; @@ -198,7 +198,7 @@ public VariantQueryResult testQuery(Query query, QueryOptions options, Assert.assertTrue(dbQueryExecutor.canUseThisExecutor(query, options)); ParsedVariantQuery variantQuery = variantStorageEngine.parseQuery(query, options); - VariantQueryResult expected = dbQueryExecutor.get(new Query(variantQuery.getQuery()), new QueryOptions(options)); + VariantQueryResult expected = dbQueryExecutor.get(variantQuery); VariantQueryResult unfilteredResult = null; VariantQueryResult result = null; @@ -237,7 +237,7 @@ public VariantQueryResult testQuery(Query query, QueryOptions options, QueryOptions emptyOptions = new QueryOptions(); emptyOptions.putIfNotEmpty(QueryOptions.INCLUDE, options.getString(QueryOptions.INCLUDE)); emptyOptions.putIfNotEmpty(QueryOptions.EXCLUDE, options.getString(QueryOptions.EXCLUDE)); - unfilteredResult = dbQueryExecutor.get(emptyQuery, emptyOptions); + unfilteredResult = dbQueryExecutor.get(variantStorageEngine.parseQuery(emptyQuery, emptyOptions)); } for (VariantQueryExecutor variantQueryExecutor : variantQueryExecutors) { @@ -245,7 +245,7 @@ public VariantQueryResult testQuery(Query query, QueryOptions options, logger.info(""); logger.info("###################"); logger.info("### Testing " + variantQueryExecutor.getClass().getSimpleName()); - result = variantQueryExecutor.get(new Query(variantQuery.getQuery()), new QueryOptions(options)); + result = variantQueryExecutor.get(variantQuery); logger.info("### Num results : " + result.getNumResults()); logger.info("###################"); expected.getResults().sort(Comparator.comparing(Variant::toString)); From 53e9e26aa0914ed148a26d71aed40871396b05f9 Mon Sep 17 00:00:00 2001 From: JuanfeSanahuja Date: Wed, 24 Apr 2024 18:11:13 +0200 Subject: [PATCH 34/85] server: Rewrite the message to send in the sendResetPasswordMail #TASK-464 --- .../CatalogAuthenticationManager.java | 3 +- .../opencb/opencga/core/common/MailUtils.java | 47 ++++++++++++------- 2 files changed, 31 insertions(+), 19 deletions(-) diff --git a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/auth/authentication/CatalogAuthenticationManager.java b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/auth/authentication/CatalogAuthenticationManager.java index 2f8f476f828..2c14d8c78fa 100644 --- a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/auth/authentication/CatalogAuthenticationManager.java +++ b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/auth/authentication/CatalogAuthenticationManager.java @@ -133,7 +133,8 @@ public OpenCGAResult resetPassword(String userId) throws CatalogException { String mailHost = this.emailConfig.getHost(); String mailPort = this.emailConfig.getPort(); try { - MailUtils.sendResetPasswordMail(email, newPassword, mailUser, mailPassword, mailHost, mailPort); + MailUtils.sendResetPasswordMail(email, newPassword, mailUser, mailPassword, mailHost, mailPort, + "true", ((User) user.getResults().get(0)).getName()); result = userDBAdaptor.resetPassword(userId, email, newPassword); } catch (Exception e) { throw new CatalogException("Email could not be sent.", e); diff --git a/opencga-core/src/main/java/org/opencb/opencga/core/common/MailUtils.java b/opencga-core/src/main/java/org/opencb/opencga/core/common/MailUtils.java index 19338531443..7181db48b89 100644 --- a/opencga-core/src/main/java/org/opencb/opencga/core/common/MailUtils.java +++ b/opencga-core/src/main/java/org/opencb/opencga/core/common/MailUtils.java @@ -16,6 +16,8 @@ package org.opencb.opencga.core.common; +import org.opencb.opencga.core.models.user.User; +import org.opencb.opencga.core.response.OpenCGAResult; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -33,13 +35,7 @@ public class MailUtils { private static final Logger logger = LoggerFactory.getLogger(MailUtils.class); public static void sendResetPasswordMail(String to, String newPassword, final String mailUser, final String mailPassword, - String mailHost, String mailPort) throws Exception { - sendResetPasswordMail(to, newPassword, mailUser, mailPassword, - mailHost, mailPort, "true"); - } - - public static void sendResetPasswordMail(String to, String newPassword, final String mailUser, final String mailPassword, - String mailHost, String mailPort, String ssl) throws Exception { + String mailHost, String mailPort, String ssl, String UserName) throws Exception { Properties props = new Properties(); props.put("mail.smtp.auth", "true"); @@ -59,20 +55,35 @@ protected PasswordAuthentication getPasswordAuthentication() { message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(to)); - message.setSubject("Your password has been reset"); - message.setText("Hello, \n" + - "You can now login using this new password:" + - "\n\n" + - newPassword + - "\n\n\n" + - "Please change it when you first login" + - "\n\n" + - "Best regards,\n\n" + - "Systems Genomics Laboratory" + - "\n"); + message.setSubject("XetaBase: Password Reset"); + message.setText(getEmailContent(UserName,newPassword)); Transport.send(message); } + public static String getEmailContent(String userId, String temporaryPassword) { + StringBuilder sb = new StringBuilder(); + + sb.append("Hi ").append(userId).append(",\n\n"); + sb.append("We confirm that your password has been successfully reset.\n\n"); + sb.append("Please find your new login credentials below:\n\n"); + sb.append("User ID: ").append(userId).append("\n"); + sb.append("Temporary Password: ").append(temporaryPassword).append("\n\n"); + sb.append("For your security, we strongly recommend that you log in using the temporary password provided "); + sb.append("and promptly create a new password that is unique and known only to you. "); + sb.append("You can change your password by accessing \"Your Profile > Change Password\" in your User Profile.\n\n"); + sb.append("If you did not request a password reset, please contact our support team immediately at support@zettagenomics.com.\n\n"); + sb.append("Best regards,\n\n"); + sb.append("ZettaGenomics Support Team \n\n"); + sb.append("*This email and any attachments are confidential and may contain privileged information " + + "intended solely for the use of the individual or entity to whom they are addressed. " + + "If you have received this email in error, please notify the sender immediately and delete the email" + + " and any attachments from your system. Any unauthorized use, disclosure, distribution, " + + "or copying of this email or its attachments is strictly prohibited.*"); + + + return sb.toString(); + } + public static void sendMail(String smtpServer, String to, String from, String subject, String body) throws Exception { Properties props = System.getProperties(); From de1e789027bb6acc07a5cf916b2c1d3bf0190abc Mon Sep 17 00:00:00 2001 From: JuanfeSanahuja Date: Thu, 25 Apr 2024 11:56:43 +0200 Subject: [PATCH 35/85] cli: Regenerate client and command line #TASK-6111 --- .../app/cli/main/OpenCgaCompleter.java | 2 +- .../app/cli/main/OpencgaCliOptionsParser.java | 2 +- .../AnalysisClinicalCommandOptions.java | 4 ++-- .../AnalysisVariantCommandOptions.java | 8 +++---- opencga-client/src/main/R/R/Admin-methods.R | 2 +- .../src/main/R/R/Alignment-methods.R | 2 +- opencga-client/src/main/R/R/AllGenerics.R | 22 +++++++++---------- .../src/main/R/R/Clinical-methods.R | 8 +++---- opencga-client/src/main/R/R/Cohort-methods.R | 4 ++-- opencga-client/src/main/R/R/Family-methods.R | 4 ++-- opencga-client/src/main/R/R/File-methods.R | 4 ++-- opencga-client/src/main/R/R/GA4GH-methods.R | 4 ++-- .../src/main/R/R/Individual-methods.R | 4 ++-- opencga-client/src/main/R/R/Job-methods.R | 4 ++-- opencga-client/src/main/R/R/Meta-methods.R | 2 +- .../src/main/R/R/Operation-methods.R | 2 +- opencga-client/src/main/R/R/Panel-methods.R | 4 ++-- opencga-client/src/main/R/R/Project-methods.R | 2 +- opencga-client/src/main/R/R/Sample-methods.R | 4 ++-- opencga-client/src/main/R/R/Study-methods.R | 4 ++-- opencga-client/src/main/R/R/User-methods.R | 4 ++-- opencga-client/src/main/R/R/Variant-methods.R | 10 ++++----- .../client/rest/clients/AdminClient.java | 2 +- .../client/rest/clients/AlignmentClient.java | 2 +- .../rest/clients/ClinicalAnalysisClient.java | 6 ++--- .../client/rest/clients/CohortClient.java | 2 +- .../rest/clients/DiseasePanelClient.java | 2 +- .../client/rest/clients/FamilyClient.java | 2 +- .../client/rest/clients/FileClient.java | 2 +- .../client/rest/clients/GA4GHClient.java | 2 +- .../client/rest/clients/IndividualClient.java | 2 +- .../client/rest/clients/JobClient.java | 2 +- .../client/rest/clients/MetaClient.java | 2 +- .../client/rest/clients/ProjectClient.java | 2 +- .../client/rest/clients/SampleClient.java | 2 +- .../client/rest/clients/StudyClient.java | 2 +- .../client/rest/clients/UserClient.java | 2 +- .../client/rest/clients/VariantClient.java | 10 ++++----- .../rest/clients/VariantOperationClient.java | 2 +- opencga-client/src/main/javascript/Admin.js | 2 +- .../src/main/javascript/Alignment.js | 2 +- .../src/main/javascript/ClinicalAnalysis.js | 7 +++--- opencga-client/src/main/javascript/Cohort.js | 2 +- .../src/main/javascript/DiseasePanel.js | 2 +- opencga-client/src/main/javascript/Family.js | 2 +- opencga-client/src/main/javascript/File.js | 2 +- opencga-client/src/main/javascript/GA4GH.js | 2 +- .../src/main/javascript/Individual.js | 2 +- opencga-client/src/main/javascript/Job.js | 2 +- opencga-client/src/main/javascript/Meta.js | 2 +- opencga-client/src/main/javascript/Project.js | 2 +- opencga-client/src/main/javascript/Sample.js | 2 +- opencga-client/src/main/javascript/Study.js | 2 +- opencga-client/src/main/javascript/User.js | 2 +- opencga-client/src/main/javascript/Variant.js | 12 +++++----- .../src/main/javascript/VariantOperation.js | 2 +- .../pyopencga/rest_clients/admin_client.py | 2 +- .../rest_clients/alignment_client.py | 2 +- .../rest_clients/clinical_analysis_client.py | 8 +++---- .../pyopencga/rest_clients/cohort_client.py | 2 +- .../rest_clients/disease_panel_client.py | 2 +- .../pyopencga/rest_clients/family_client.py | 2 +- .../pyopencga/rest_clients/file_client.py | 2 +- .../pyopencga/rest_clients/ga4gh_client.py | 2 +- .../rest_clients/individual_client.py | 2 +- .../pyopencga/rest_clients/job_client.py | 2 +- .../pyopencga/rest_clients/meta_client.py | 2 +- .../pyopencga/rest_clients/project_client.py | 2 +- .../pyopencga/rest_clients/sample_client.py | 2 +- .../pyopencga/rest_clients/study_client.py | 2 +- .../pyopencga/rest_clients/user_client.py | 2 +- .../pyopencga/rest_clients/variant_client.py | 14 ++++++------ .../rest_clients/variant_operation_client.py | 2 +- 73 files changed, 125 insertions(+), 128 deletions(-) diff --git a/opencga-app/src/main/java/org/opencb/opencga/app/cli/main/OpenCgaCompleter.java b/opencga-app/src/main/java/org/opencb/opencga/app/cli/main/OpenCgaCompleter.java index 36e23f42168..b0db2e99473 100644 --- a/opencga-app/src/main/java/org/opencb/opencga/app/cli/main/OpenCgaCompleter.java +++ b/opencga-app/src/main/java/org/opencb/opencga/app/cli/main/OpenCgaCompleter.java @@ -1,5 +1,5 @@ /* -* Copyright 2015-2024-04-17 OpenCB +* Copyright 2015-2024-04-25 OpenCB * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/opencga-app/src/main/java/org/opencb/opencga/app/cli/main/OpencgaCliOptionsParser.java b/opencga-app/src/main/java/org/opencb/opencga/app/cli/main/OpencgaCliOptionsParser.java index a50c83bbdc6..c5d4c21c8d2 100644 --- a/opencga-app/src/main/java/org/opencb/opencga/app/cli/main/OpencgaCliOptionsParser.java +++ b/opencga-app/src/main/java/org/opencb/opencga/app/cli/main/OpencgaCliOptionsParser.java @@ -1,5 +1,5 @@ /* -* Copyright 2015-2024-04-17 OpenCB +* Copyright 2015-2024-04-25 OpenCB * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/opencga-app/src/main/java/org/opencb/opencga/app/cli/main/options/AnalysisClinicalCommandOptions.java b/opencga-app/src/main/java/org/opencb/opencga/app/cli/main/options/AnalysisClinicalCommandOptions.java index 3a7ccffd4bd..592dbfc3efc 100644 --- a/opencga-app/src/main/java/org/opencb/opencga/app/cli/main/options/AnalysisClinicalCommandOptions.java +++ b/opencga-app/src/main/java/org/opencb/opencga/app/cli/main/options/AnalysisClinicalCommandOptions.java @@ -1687,7 +1687,7 @@ public class QueryVariantCommandOptions { @Parameter(names = {"--include-interpretation"}, description = "Interpretation ID to include the fields related to this interpretation", required = false, arity = 1) public String includeInterpretation; - @Parameter(names = {"--id"}, description = "List of IDs, these can be rs IDs (dbSNP) or variants in the format chrom:start:ref:alt, e.g. rs116600158,19:7177679:C:T", required = false, arity = 1) + @Parameter(names = {"--id"}, description = "List of variant IDs in the format chrom:start:ref:alt, e.g. 19:7177679:C:T", required = false, arity = 1) public String id; @Parameter(names = {"--region"}, description = "List of regions, these can be just a single chromosome name or regions in the format chr:start-end, e.g.: 2,3:100000-200000", required = false, arity = 1) @@ -1768,7 +1768,7 @@ public class QueryVariantCommandOptions { @Parameter(names = {"--ct"}, description = "List of SO consequence types, e.g. missense_variant,stop_lost or SO:0001583,SO:0001578. Accepts aliases 'loss_of_function' and 'protein_altering'", required = false, arity = 1) public String ct; - @Parameter(names = {"--xref"}, description = "List of any external reference, these can be genes, proteins or variants. Accepted IDs include HGNC, Ensembl genes, dbSNP, ClinVar, HPO, Cosmic, ...", required = false, arity = 1) + @Parameter(names = {"--xref"}, description = "List of any external reference, these can be genes, proteins or variants. Accepted IDs include HGNC, Ensembl genes, dbSNP, ClinVar, HPO, Cosmic, HGVS ...", required = false, arity = 1) public String xref; @Parameter(names = {"--biotype"}, description = "List of biotypes, e.g. protein_coding", required = false, arity = 1) diff --git a/opencga-app/src/main/java/org/opencb/opencga/app/cli/main/options/AnalysisVariantCommandOptions.java b/opencga-app/src/main/java/org/opencb/opencga/app/cli/main/options/AnalysisVariantCommandOptions.java index f4a675b0e53..069e1ef9322 100644 --- a/opencga-app/src/main/java/org/opencb/opencga/app/cli/main/options/AnalysisVariantCommandOptions.java +++ b/opencga-app/src/main/java/org/opencb/opencga/app/cli/main/options/AnalysisVariantCommandOptions.java @@ -177,7 +177,7 @@ public class AggregationStatsCommandOptions { @Parameter(names = {"--ct"}, description = "List of SO consequence types, e.g. missense_variant,stop_lost or SO:0001583,SO:0001578. Accepts aliases 'loss_of_function' and 'protein_altering'", required = false, arity = 1) public String ct; - @Parameter(names = {"--xref"}, description = "List of any external reference, these can be genes, proteins or variants. Accepted IDs include HGNC, Ensembl genes, dbSNP, ClinVar, HPO, Cosmic, ...", required = false, arity = 1) + @Parameter(names = {"--xref"}, description = "List of any external reference, these can be genes, proteins or variants. Accepted IDs include HGNC, Ensembl genes, dbSNP, ClinVar, HPO, Cosmic, HGVS ...", required = false, arity = 1) public String xref; @Parameter(names = {"--biotype"}, description = "List of biotypes, e.g. protein_coding", required = false, arity = 1) @@ -259,7 +259,7 @@ public class QueryAnnotationCommandOptions { @ParametersDelegate public CommonCommandOptions commonOptions = commonCommandOptions; - @Parameter(names = {"--id"}, description = "List of IDs, these can be rs IDs (dbSNP) or variants in the format chrom:start:ref:alt, e.g. rs116600158,19:7177679:C:T", required = false, arity = 1) + @Parameter(names = {"--id"}, description = "List of variant IDs in the format chrom:start:ref:alt, e.g. 19:7177679:C:T", required = false, arity = 1) public String id; @Parameter(names = {"--region"}, description = "List of regions, these can be just a single chromosome name or regions in the format chr:start-end, e.g.: 2,3:100000-200000", required = false, arity = 1) @@ -1614,7 +1614,7 @@ public class QueryCommandOptions { @Parameter(names = {"--saved-filter"}, description = "Use a saved filter at User level", required = false, arity = 1) public String savedFilter; - @Parameter(names = {"--id"}, description = "List of IDs, these can be rs IDs (dbSNP) or variants in the format chrom:start:ref:alt, e.g. rs116600158,19:7177679:C:T", required = false, arity = 1) + @Parameter(names = {"--id"}, description = "List of variant IDs in the format chrom:start:ref:alt, e.g. 19:7177679:C:T", required = false, arity = 1) public String id; @Parameter(names = {"--region"}, description = "List of regions, these can be just a single chromosome name or regions in the format chr:start-end, e.g.: 2,3:100000-200000", required = false, arity = 1) @@ -1740,7 +1740,7 @@ public class QueryCommandOptions { @Parameter(names = {"--ct"}, description = "List of SO consequence types, e.g. missense_variant,stop_lost or SO:0001583,SO:0001578. Accepts aliases 'loss_of_function' and 'protein_altering'", required = false, arity = 1) public String ct; - @Parameter(names = {"--xref"}, description = "List of any external reference, these can be genes, proteins or variants. Accepted IDs include HGNC, Ensembl genes, dbSNP, ClinVar, HPO, Cosmic, ...", required = false, arity = 1) + @Parameter(names = {"--xref"}, description = "List of any external reference, these can be genes, proteins or variants. Accepted IDs include HGNC, Ensembl genes, dbSNP, ClinVar, HPO, Cosmic, HGVS ...", required = false, arity = 1) public String xref; @Parameter(names = {"--biotype"}, description = "List of biotypes, e.g. protein_coding", required = false, arity = 1) diff --git a/opencga-client/src/main/R/R/Admin-methods.R b/opencga-client/src/main/R/R/Admin-methods.R index b1075de496d..02700c96173 100644 --- a/opencga-client/src/main/R/R/Admin-methods.R +++ b/opencga-client/src/main/R/R/Admin-methods.R @@ -2,7 +2,7 @@ # WARNING: AUTOGENERATED CODE # # This code was generated by a tool. -# Autogenerated on: 2024-04-17 +# Autogenerated on: 2024-04-25 # # Manual changes to this file may cause unexpected behavior in your application. # Manual changes to this file will be overwritten if the code is regenerated. diff --git a/opencga-client/src/main/R/R/Alignment-methods.R b/opencga-client/src/main/R/R/Alignment-methods.R index 789a0eff6d1..e367674574c 100644 --- a/opencga-client/src/main/R/R/Alignment-methods.R +++ b/opencga-client/src/main/R/R/Alignment-methods.R @@ -2,7 +2,7 @@ # WARNING: AUTOGENERATED CODE # # This code was generated by a tool. -# Autogenerated on: 2024-04-17 +# Autogenerated on: 2024-04-25 # # Manual changes to this file may cause unexpected behavior in your application. # Manual changes to this file will be overwritten if the code is regenerated. diff --git a/opencga-client/src/main/R/R/AllGenerics.R b/opencga-client/src/main/R/R/AllGenerics.R index b6c6eea6fc7..3f65ad80933 100644 --- a/opencga-client/src/main/R/R/AllGenerics.R +++ b/opencga-client/src/main/R/R/AllGenerics.R @@ -1,6 +1,6 @@ # ############################################################################## ## UserClient -setGeneric("userClient", function(OpencgaR, filterId, user, users, endpointName, params=NULL, ...) +setGeneric("userClient", function(OpencgaR, users, user, filterId, endpointName, params=NULL, ...) standardGeneric("userClient")) # ############################################################################## @@ -10,42 +10,42 @@ setGeneric("projectClient", function(OpencgaR, projects, project, endpointName, # ############################################################################## ## StudyClient -setGeneric("studyClient", function(OpencgaR, templateId, variableSet, members, study, group, studies, endpointName, params=NULL, ...) +setGeneric("studyClient", function(OpencgaR, studies, members, variableSet, group, templateId, study, endpointName, params=NULL, ...) standardGeneric("studyClient")) # ############################################################################## ## FileClient -setGeneric("fileClient", function(OpencgaR, files, members, folder, file, annotationSet, endpointName, params=NULL, ...) +setGeneric("fileClient", function(OpencgaR, members, file, folder, annotationSet, files, endpointName, params=NULL, ...) standardGeneric("fileClient")) # ############################################################################## ## JobClient -setGeneric("jobClient", function(OpencgaR, jobs, job, members, endpointName, params=NULL, ...) +setGeneric("jobClient", function(OpencgaR, jobs, members, job, endpointName, params=NULL, ...) standardGeneric("jobClient")) # ############################################################################## ## SampleClient -setGeneric("sampleClient", function(OpencgaR, samples, annotationSet, members, sample, endpointName, params=NULL, ...) +setGeneric("sampleClient", function(OpencgaR, annotationSet, members, samples, sample, endpointName, params=NULL, ...) standardGeneric("sampleClient")) # ############################################################################## ## IndividualClient -setGeneric("individualClient", function(OpencgaR, annotationSet, individuals, members, individual, endpointName, params=NULL, ...) +setGeneric("individualClient", function(OpencgaR, annotationSet, individual, members, individuals, endpointName, params=NULL, ...) standardGeneric("individualClient")) # ############################################################################## ## FamilyClient -setGeneric("familyClient", function(OpencgaR, family, families, members, annotationSet, endpointName, params=NULL, ...) +setGeneric("familyClient", function(OpencgaR, family, members, annotationSet, families, endpointName, params=NULL, ...) standardGeneric("familyClient")) # ############################################################################## ## CohortClient -setGeneric("cohortClient", function(OpencgaR, cohorts, annotationSet, cohort, members, endpointName, params=NULL, ...) +setGeneric("cohortClient", function(OpencgaR, annotationSet, members, cohort, cohorts, endpointName, params=NULL, ...) standardGeneric("cohortClient")) # ############################################################################## ## PanelClient -setGeneric("panelClient", function(OpencgaR, panels, members, endpointName, params=NULL, ...) +setGeneric("panelClient", function(OpencgaR, members, panels, endpointName, params=NULL, ...) standardGeneric("panelClient")) # ############################################################################## @@ -60,7 +60,7 @@ setGeneric("variantClient", function(OpencgaR, endpointName, params=NULL, ...) # ############################################################################## ## ClinicalClient -setGeneric("clinicalClient", function(OpencgaR, members, clinicalAnalyses, clinicalAnalysis, interpretation, annotationSet, interpretations, endpointName, params=NULL, ...) +setGeneric("clinicalClient", function(OpencgaR, members, clinicalAnalyses, annotationSet, interpretations, interpretation, clinicalAnalysis, endpointName, params=NULL, ...) standardGeneric("clinicalClient")) # ############################################################################## @@ -75,7 +75,7 @@ setGeneric("metaClient", function(OpencgaR, endpointName, params=NULL, ...) # ############################################################################## ## GA4GHClient -setGeneric("ga4ghClient", function(OpencgaR, file, study, endpointName, params=NULL, ...) +setGeneric("ga4ghClient", function(OpencgaR, study, file, endpointName, params=NULL, ...) standardGeneric("ga4ghClient")) # ############################################################################## diff --git a/opencga-client/src/main/R/R/Clinical-methods.R b/opencga-client/src/main/R/R/Clinical-methods.R index 4086c5dc9f0..d1f276dc792 100644 --- a/opencga-client/src/main/R/R/Clinical-methods.R +++ b/opencga-client/src/main/R/R/Clinical-methods.R @@ -2,7 +2,7 @@ # WARNING: AUTOGENERATED CODE # # This code was generated by a tool. -# Autogenerated on: 2024-04-17 +# Autogenerated on: 2024-04-25 # # Manual changes to this file may cause unexpected behavior in your application. # Manual changes to this file will be overwritten if the code is regenerated. @@ -61,7 +61,7 @@ #' [*]: Required parameter #' @export -setMethod("clinicalClient", "OpencgaR", function(OpencgaR, members, clinicalAnalyses, clinicalAnalysis, interpretation, annotationSet, interpretations, endpointName, params=NULL, ...) { +setMethod("clinicalClient", "OpencgaR", function(OpencgaR, members, clinicalAnalyses, annotationSet, interpretations, interpretation, clinicalAnalysis, endpointName, params=NULL, ...) { switch(endpointName, #' @section Endpoint /{apiVersion}/analysis/clinical/acl/{members}/update: @@ -541,7 +541,7 @@ setMethod("clinicalClient", "OpencgaR", function(OpencgaR, members, clinicalAnal #' @param approximateCountSamplingSize Sampling size to get the approximate count. Larger values increase accuracy but also increase execution time. #' @param savedFilter Use a saved filter at User level. #' @param includeInterpretation Interpretation ID to include the fields related to this interpretation. - #' @param id List of IDs, these can be rs IDs (dbSNP) or variants in the format chrom:start:ref:alt, e.g. rs116600158,19:7177679:C:T. + #' @param id List of variant IDs in the format chrom:start:ref:alt, e.g. 19:7177679:C:T. #' @param region List of regions, these can be just a single chromosome name or regions in the format chr:start-end, e.g.: 2,3:100000-200000. #' @param type List of types, accepted values are SNV, MNV, INDEL, SV, COPY_NUMBER, COPY_NUMBER_LOSS, COPY_NUMBER_GAIN, INSERTION, DELETION, DUPLICATION, TANDEM_DUPLICATION, BREAKEND, e.g. SNV,INDEL. #' @param study Filter variants from the given studies, these can be either the numeric ID or the alias with the format user@project:study. @@ -568,7 +568,7 @@ setMethod("clinicalClient", "OpencgaR", function(OpencgaR, members, clinicalAnal #' @param familyProband Specify the proband child to use for the family segregation. #' @param gene List of genes, most gene IDs are accepted (HGNC, Ensembl gene, ...). This is an alias to 'xref' parameter. #' @param ct List of SO consequence types, e.g. missense_variant,stop_lost or SO:0001583,SO:0001578. Accepts aliases 'loss_of_function' and 'protein_altering'. - #' @param xref List of any external reference, these can be genes, proteins or variants. Accepted IDs include HGNC, Ensembl genes, dbSNP, ClinVar, HPO, Cosmic, ... + #' @param xref List of any external reference, these can be genes, proteins or variants. Accepted IDs include HGNC, Ensembl genes, dbSNP, ClinVar, HPO, Cosmic, HGVS ... #' @param biotype List of biotypes, e.g. protein_coding. #' @param proteinSubstitution Protein substitution scores include SIFT and PolyPhen. You can query using the score {protein_score}[<|>|<=|>=]{number} or the description {protein_score}[~=|=]{description} e.g. polyphen>0.1,sift=tolerant. #' @param conservation Filter by conservation score: {conservation_score}[<|>|<=|>=]{number} e.g. phastCons>0.5,phylop<0.1,gerp>0.1. diff --git a/opencga-client/src/main/R/R/Cohort-methods.R b/opencga-client/src/main/R/R/Cohort-methods.R index 4fd94649ad3..727cc6dcae3 100644 --- a/opencga-client/src/main/R/R/Cohort-methods.R +++ b/opencga-client/src/main/R/R/Cohort-methods.R @@ -2,7 +2,7 @@ # WARNING: AUTOGENERATED CODE # # This code was generated by a tool. -# Autogenerated on: 2024-04-17 +# Autogenerated on: 2024-04-25 # # Manual changes to this file may cause unexpected behavior in your application. # Manual changes to this file will be overwritten if the code is regenerated. @@ -39,7 +39,7 @@ #' [*]: Required parameter #' @export -setMethod("cohortClient", "OpencgaR", function(OpencgaR, cohorts, annotationSet, cohort, members, endpointName, params=NULL, ...) { +setMethod("cohortClient", "OpencgaR", function(OpencgaR, annotationSet, members, cohort, cohorts, endpointName, params=NULL, ...) { switch(endpointName, #' @section Endpoint /{apiVersion}/cohorts/acl/{members}/update: diff --git a/opencga-client/src/main/R/R/Family-methods.R b/opencga-client/src/main/R/R/Family-methods.R index 7df4099ebb1..3111f2a51ed 100644 --- a/opencga-client/src/main/R/R/Family-methods.R +++ b/opencga-client/src/main/R/R/Family-methods.R @@ -2,7 +2,7 @@ # WARNING: AUTOGENERATED CODE # # This code was generated by a tool. -# Autogenerated on: 2024-04-17 +# Autogenerated on: 2024-04-25 # # Manual changes to this file may cause unexpected behavior in your application. # Manual changes to this file will be overwritten if the code is regenerated. @@ -38,7 +38,7 @@ #' [*]: Required parameter #' @export -setMethod("familyClient", "OpencgaR", function(OpencgaR, family, families, members, annotationSet, endpointName, params=NULL, ...) { +setMethod("familyClient", "OpencgaR", function(OpencgaR, family, members, annotationSet, families, endpointName, params=NULL, ...) { switch(endpointName, #' @section Endpoint /{apiVersion}/families/acl/{members}/update: diff --git a/opencga-client/src/main/R/R/File-methods.R b/opencga-client/src/main/R/R/File-methods.R index 32930f9addc..a0c896dcffa 100644 --- a/opencga-client/src/main/R/R/File-methods.R +++ b/opencga-client/src/main/R/R/File-methods.R @@ -2,7 +2,7 @@ # WARNING: AUTOGENERATED CODE # # This code was generated by a tool. -# Autogenerated on: 2024-04-17 +# Autogenerated on: 2024-04-25 # # Manual changes to this file may cause unexpected behavior in your application. # Manual changes to this file will be overwritten if the code is regenerated. @@ -55,7 +55,7 @@ #' [*]: Required parameter #' @export -setMethod("fileClient", "OpencgaR", function(OpencgaR, files, members, folder, file, annotationSet, endpointName, params=NULL, ...) { +setMethod("fileClient", "OpencgaR", function(OpencgaR, members, file, folder, annotationSet, files, endpointName, params=NULL, ...) { switch(endpointName, #' @section Endpoint /{apiVersion}/files/acl/{members}/update: diff --git a/opencga-client/src/main/R/R/GA4GH-methods.R b/opencga-client/src/main/R/R/GA4GH-methods.R index 5fa299d9a0a..2406d77ff2c 100644 --- a/opencga-client/src/main/R/R/GA4GH-methods.R +++ b/opencga-client/src/main/R/R/GA4GH-methods.R @@ -2,7 +2,7 @@ # WARNING: AUTOGENERATED CODE # # This code was generated by a tool. -# Autogenerated on: 2024-04-17 +# Autogenerated on: 2024-04-25 # # Manual changes to this file may cause unexpected behavior in your application. # Manual changes to this file will be overwritten if the code is regenerated. @@ -31,7 +31,7 @@ #' [*]: Required parameter #' @export -setMethod("ga4ghClient", "OpencgaR", function(OpencgaR, file, study, endpointName, params=NULL, ...) { +setMethod("ga4ghClient", "OpencgaR", function(OpencgaR, study, file, endpointName, params=NULL, ...) { switch(endpointName, #' @section Endpoint /{apiVersion}/ga4gh/reads/search: diff --git a/opencga-client/src/main/R/R/Individual-methods.R b/opencga-client/src/main/R/R/Individual-methods.R index 5561a1988b1..b48136ae582 100644 --- a/opencga-client/src/main/R/R/Individual-methods.R +++ b/opencga-client/src/main/R/R/Individual-methods.R @@ -2,7 +2,7 @@ # WARNING: AUTOGENERATED CODE # # This code was generated by a tool. -# Autogenerated on: 2024-04-17 +# Autogenerated on: 2024-04-25 # # Manual changes to this file may cause unexpected behavior in your application. # Manual changes to this file will be overwritten if the code is regenerated. @@ -39,7 +39,7 @@ #' [*]: Required parameter #' @export -setMethod("individualClient", "OpencgaR", function(OpencgaR, annotationSet, individuals, members, individual, endpointName, params=NULL, ...) { +setMethod("individualClient", "OpencgaR", function(OpencgaR, annotationSet, individual, members, individuals, endpointName, params=NULL, ...) { switch(endpointName, #' @section Endpoint /{apiVersion}/individuals/acl/{members}/update: diff --git a/opencga-client/src/main/R/R/Job-methods.R b/opencga-client/src/main/R/R/Job-methods.R index 4d943c46e40..b6c47021122 100644 --- a/opencga-client/src/main/R/R/Job-methods.R +++ b/opencga-client/src/main/R/R/Job-methods.R @@ -2,7 +2,7 @@ # WARNING: AUTOGENERATED CODE # # This code was generated by a tool. -# Autogenerated on: 2024-04-17 +# Autogenerated on: 2024-04-25 # # Manual changes to this file may cause unexpected behavior in your application. # Manual changes to this file will be overwritten if the code is regenerated. @@ -40,7 +40,7 @@ #' [*]: Required parameter #' @export -setMethod("jobClient", "OpencgaR", function(OpencgaR, jobs, job, members, endpointName, params=NULL, ...) { +setMethod("jobClient", "OpencgaR", function(OpencgaR, jobs, members, job, endpointName, params=NULL, ...) { switch(endpointName, #' @section Endpoint /{apiVersion}/jobs/acl/{members}/update: diff --git a/opencga-client/src/main/R/R/Meta-methods.R b/opencga-client/src/main/R/R/Meta-methods.R index 8bd1b850f98..6e427607ade 100644 --- a/opencga-client/src/main/R/R/Meta-methods.R +++ b/opencga-client/src/main/R/R/Meta-methods.R @@ -2,7 +2,7 @@ # WARNING: AUTOGENERATED CODE # # This code was generated by a tool. -# Autogenerated on: 2024-04-17 +# Autogenerated on: 2024-04-25 # # Manual changes to this file may cause unexpected behavior in your application. # Manual changes to this file will be overwritten if the code is regenerated. diff --git a/opencga-client/src/main/R/R/Operation-methods.R b/opencga-client/src/main/R/R/Operation-methods.R index c5f02d3de48..0431fa7a235 100644 --- a/opencga-client/src/main/R/R/Operation-methods.R +++ b/opencga-client/src/main/R/R/Operation-methods.R @@ -2,7 +2,7 @@ # WARNING: AUTOGENERATED CODE # # This code was generated by a tool. -# Autogenerated on: 2024-04-17 +# Autogenerated on: 2024-04-25 # # Manual changes to this file may cause unexpected behavior in your application. # Manual changes to this file will be overwritten if the code is regenerated. diff --git a/opencga-client/src/main/R/R/Panel-methods.R b/opencga-client/src/main/R/R/Panel-methods.R index 4a5fab649b9..ab0e75d32a3 100644 --- a/opencga-client/src/main/R/R/Panel-methods.R +++ b/opencga-client/src/main/R/R/Panel-methods.R @@ -2,7 +2,7 @@ # WARNING: AUTOGENERATED CODE # # This code was generated by a tool. -# Autogenerated on: 2024-04-17 +# Autogenerated on: 2024-04-25 # # Manual changes to this file may cause unexpected behavior in your application. # Manual changes to this file will be overwritten if the code is regenerated. @@ -36,7 +36,7 @@ #' [*]: Required parameter #' @export -setMethod("panelClient", "OpencgaR", function(OpencgaR, panels, members, endpointName, params=NULL, ...) { +setMethod("panelClient", "OpencgaR", function(OpencgaR, members, panels, endpointName, params=NULL, ...) { switch(endpointName, #' @section Endpoint /{apiVersion}/panels/acl/{members}/update: diff --git a/opencga-client/src/main/R/R/Project-methods.R b/opencga-client/src/main/R/R/Project-methods.R index 740abc79fb0..c75b843e860 100644 --- a/opencga-client/src/main/R/R/Project-methods.R +++ b/opencga-client/src/main/R/R/Project-methods.R @@ -2,7 +2,7 @@ # WARNING: AUTOGENERATED CODE # # This code was generated by a tool. -# Autogenerated on: 2024-04-17 +# Autogenerated on: 2024-04-25 # # Manual changes to this file may cause unexpected behavior in your application. # Manual changes to this file will be overwritten if the code is regenerated. diff --git a/opencga-client/src/main/R/R/Sample-methods.R b/opencga-client/src/main/R/R/Sample-methods.R index 89427790a5f..2ab6077f9b4 100644 --- a/opencga-client/src/main/R/R/Sample-methods.R +++ b/opencga-client/src/main/R/R/Sample-methods.R @@ -2,7 +2,7 @@ # WARNING: AUTOGENERATED CODE # # This code was generated by a tool. -# Autogenerated on: 2024-04-17 +# Autogenerated on: 2024-04-25 # # Manual changes to this file may cause unexpected behavior in your application. # Manual changes to this file will be overwritten if the code is regenerated. @@ -39,7 +39,7 @@ #' [*]: Required parameter #' @export -setMethod("sampleClient", "OpencgaR", function(OpencgaR, samples, annotationSet, members, sample, endpointName, params=NULL, ...) { +setMethod("sampleClient", "OpencgaR", function(OpencgaR, annotationSet, members, samples, sample, endpointName, params=NULL, ...) { switch(endpointName, #' @section Endpoint /{apiVersion}/samples/acl/{members}/update: diff --git a/opencga-client/src/main/R/R/Study-methods.R b/opencga-client/src/main/R/R/Study-methods.R index 7c9c3d1ea80..a3d83d55ecd 100644 --- a/opencga-client/src/main/R/R/Study-methods.R +++ b/opencga-client/src/main/R/R/Study-methods.R @@ -2,7 +2,7 @@ # WARNING: AUTOGENERATED CODE # # This code was generated by a tool. -# Autogenerated on: 2024-04-17 +# Autogenerated on: 2024-04-25 # # Manual changes to this file may cause unexpected behavior in your application. # Manual changes to this file will be overwritten if the code is regenerated. @@ -46,7 +46,7 @@ #' [*]: Required parameter #' @export -setMethod("studyClient", "OpencgaR", function(OpencgaR, templateId, variableSet, members, study, group, studies, endpointName, params=NULL, ...) { +setMethod("studyClient", "OpencgaR", function(OpencgaR, studies, members, variableSet, group, templateId, study, endpointName, params=NULL, ...) { switch(endpointName, #' @section Endpoint /{apiVersion}/studies/acl/{members}/update: diff --git a/opencga-client/src/main/R/R/User-methods.R b/opencga-client/src/main/R/R/User-methods.R index 5de14f31ef3..266a3ee51d5 100644 --- a/opencga-client/src/main/R/R/User-methods.R +++ b/opencga-client/src/main/R/R/User-methods.R @@ -2,7 +2,7 @@ # WARNING: AUTOGENERATED CODE # # This code was generated by a tool. -# Autogenerated on: 2024-04-17 +# Autogenerated on: 2024-04-25 # # Manual changes to this file may cause unexpected behavior in your application. # Manual changes to this file will be overwritten if the code is regenerated. @@ -38,7 +38,7 @@ #' [*]: Required parameter #' @export -setMethod("userClient", "OpencgaR", function(OpencgaR, filterId, user, users, endpointName, params=NULL, ...) { +setMethod("userClient", "OpencgaR", function(OpencgaR, users, user, filterId, endpointName, params=NULL, ...) { switch(endpointName, #' @section Endpoint /{apiVersion}/users/login: diff --git a/opencga-client/src/main/R/R/Variant-methods.R b/opencga-client/src/main/R/R/Variant-methods.R index da20cde0ff2..c17b30b4f0c 100644 --- a/opencga-client/src/main/R/R/Variant-methods.R +++ b/opencga-client/src/main/R/R/Variant-methods.R @@ -2,7 +2,7 @@ # WARNING: AUTOGENERATED CODE # # This code was generated by a tool. -# Autogenerated on: 2024-04-17 +# Autogenerated on: 2024-04-25 # # Manual changes to this file may cause unexpected behavior in your application. # Manual changes to this file will be overwritten if the code is regenerated. @@ -88,7 +88,7 @@ setMethod("variantClient", "OpencgaR", function(OpencgaR, endpointName, params=N #' @param annotationExists Return only annotated variants. #' @param gene List of genes, most gene IDs are accepted (HGNC, Ensembl gene, ...). This is an alias to 'xref' parameter. #' @param ct List of SO consequence types, e.g. missense_variant,stop_lost or SO:0001583,SO:0001578. Accepts aliases 'loss_of_function' and 'protein_altering'. - #' @param xref List of any external reference, these can be genes, proteins or variants. Accepted IDs include HGNC, Ensembl genes, dbSNP, ClinVar, HPO, Cosmic, ... + #' @param xref List of any external reference, these can be genes, proteins or variants. Accepted IDs include HGNC, Ensembl genes, dbSNP, ClinVar, HPO, Cosmic, HGVS ... #' @param biotype List of biotypes, e.g. protein_coding. #' @param proteinSubstitution Protein substitution scores include SIFT and PolyPhen. You can query using the score {protein_score}[<|>|<=|>=]{number} or the description {protein_score}[~=|=]{description} e.g. polyphen>0.1,sift=tolerant. #' @param conservation Filter by conservation score: {conservation_score}[<|>|<=|>=]{number} e.g. phastCons>0.5,phylop<0.1,gerp>0.1. @@ -122,7 +122,7 @@ setMethod("variantClient", "OpencgaR", function(OpencgaR, endpointName, params=N #' @section Endpoint /{apiVersion}/analysis/variant/annotation/query: #' Query variant annotations from any saved versions. - #' @param id List of IDs, these can be rs IDs (dbSNP) or variants in the format chrom:start:ref:alt, e.g. rs116600158,19:7177679:C:T. + #' @param id List of variant IDs in the format chrom:start:ref:alt, e.g. 19:7177679:C:T. #' @param region List of regions, these can be just a single chromosome name or regions in the format chr:start-end, e.g.: 2,3:100000-200000. #' @param include Fields included in the response, whole JSON path must be provided. #' @param exclude Fields excluded in the response, whole JSON path must be provided. @@ -425,7 +425,7 @@ setMethod("variantClient", "OpencgaR", function(OpencgaR, endpointName, params=N #' @param approximateCount Get an approximate count, instead of an exact total count. Reduces execution time. #' @param approximateCountSamplingSize Sampling size to get the approximate count. Larger values increase accuracy but also increase execution time. #' @param savedFilter Use a saved filter at User level. - #' @param id List of IDs, these can be rs IDs (dbSNP) or variants in the format chrom:start:ref:alt, e.g. rs116600158,19:7177679:C:T. + #' @param id List of variant IDs in the format chrom:start:ref:alt, e.g. 19:7177679:C:T. #' @param region List of regions, these can be just a single chromosome name or regions in the format chr:start-end, e.g.: 2,3:100000-200000. #' @param type List of types, accepted values are SNV, MNV, INDEL, SV, COPY_NUMBER, COPY_NUMBER_LOSS, COPY_NUMBER_GAIN, INSERTION, DELETION, DUPLICATION, TANDEM_DUPLICATION, BREAKEND, e.g. SNV,INDEL. #' @param reference Reference allele. @@ -467,7 +467,7 @@ setMethod("variantClient", "OpencgaR", function(OpencgaR, endpointName, params=N #' @param annotationExists Return only annotated variants. #' @param gene List of genes, most gene IDs are accepted (HGNC, Ensembl gene, ...). This is an alias to 'xref' parameter. #' @param ct List of SO consequence types, e.g. missense_variant,stop_lost or SO:0001583,SO:0001578. Accepts aliases 'loss_of_function' and 'protein_altering'. - #' @param xref List of any external reference, these can be genes, proteins or variants. Accepted IDs include HGNC, Ensembl genes, dbSNP, ClinVar, HPO, Cosmic, ... + #' @param xref List of any external reference, these can be genes, proteins or variants. Accepted IDs include HGNC, Ensembl genes, dbSNP, ClinVar, HPO, Cosmic, HGVS ... #' @param biotype List of biotypes, e.g. protein_coding. #' @param proteinSubstitution Protein substitution scores include SIFT and PolyPhen. You can query using the score {protein_score}[<|>|<=|>=]{number} or the description {protein_score}[~=|=]{description} e.g. polyphen>0.1,sift=tolerant. #' @param conservation Filter by conservation score: {conservation_score}[<|>|<=|>=]{number} e.g. phastCons>0.5,phylop<0.1,gerp>0.1. diff --git a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/AdminClient.java b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/AdminClient.java index 91df6bfd606..5601a4e5329 100644 --- a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/AdminClient.java +++ b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/AdminClient.java @@ -36,7 +36,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. -* Autogenerated on: 2024-04-17 +* Autogenerated on: 2024-04-25 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. diff --git a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/AlignmentClient.java b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/AlignmentClient.java index 32033b437ce..ea517320b92 100644 --- a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/AlignmentClient.java +++ b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/AlignmentClient.java @@ -40,7 +40,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. -* Autogenerated on: 2024-04-17 +* Autogenerated on: 2024-04-25 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. diff --git a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/ClinicalAnalysisClient.java b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/ClinicalAnalysisClient.java index 799a12f0734..e80fc6b059f 100644 --- a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/ClinicalAnalysisClient.java +++ b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/ClinicalAnalysisClient.java @@ -54,7 +54,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. -* Autogenerated on: 2024-04-17 +* Autogenerated on: 2024-04-25 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. @@ -698,7 +698,7 @@ public RestResponse search(ObjectMap params) throws ClientExce * execution time. * savedFilter: Use a saved filter at User level. * includeInterpretation: Interpretation ID to include the fields related to this interpretation. - * id: List of IDs, these can be rs IDs (dbSNP) or variants in the format chrom:start:ref:alt, e.g. rs116600158,19:7177679:C:T. + * id: List of variant IDs in the format chrom:start:ref:alt, e.g. 19:7177679:C:T. * region: List of regions, these can be just a single chromosome name or regions in the format chr:start-end, e.g.: * 2,3:100000-200000. * type: List of types, accepted values are SNV, MNV, INDEL, SV, COPY_NUMBER, COPY_NUMBER_LOSS, COPY_NUMBER_GAIN, INSERTION, @@ -746,7 +746,7 @@ public RestResponse search(ObjectMap params) throws ClientExce * ct: List of SO consequence types, e.g. missense_variant,stop_lost or SO:0001583,SO:0001578. Accepts aliases 'loss_of_function' * and 'protein_altering'. * xref: List of any external reference, these can be genes, proteins or variants. Accepted IDs include HGNC, Ensembl genes, - * dbSNP, ClinVar, HPO, Cosmic, ... + * dbSNP, ClinVar, HPO, Cosmic, HGVS ... * biotype: List of biotypes, e.g. protein_coding. * proteinSubstitution: Protein substitution scores include SIFT and PolyPhen. You can query using the score * {protein_score}[<|>|<=|>=]{number} or the description {protein_score}[~=|=]{description} e.g. polyphen>0.1,sift=tolerant. diff --git a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/CohortClient.java b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/CohortClient.java index f9d16f17762..64dfe81be6b 100644 --- a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/CohortClient.java +++ b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/CohortClient.java @@ -37,7 +37,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. -* Autogenerated on: 2024-04-17 +* Autogenerated on: 2024-04-25 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. diff --git a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/DiseasePanelClient.java b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/DiseasePanelClient.java index 92c14116c8e..ba0285bd561 100644 --- a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/DiseasePanelClient.java +++ b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/DiseasePanelClient.java @@ -35,7 +35,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. -* Autogenerated on: 2024-04-17 +* Autogenerated on: 2024-04-25 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. diff --git a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/FamilyClient.java b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/FamilyClient.java index 826c7203f08..e7c9399f9d6 100644 --- a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/FamilyClient.java +++ b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/FamilyClient.java @@ -36,7 +36,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. -* Autogenerated on: 2024-04-17 +* Autogenerated on: 2024-04-25 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. diff --git a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/FileClient.java b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/FileClient.java index 3f16dccce20..43814c27514 100644 --- a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/FileClient.java +++ b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/FileClient.java @@ -44,7 +44,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. -* Autogenerated on: 2024-04-17 +* Autogenerated on: 2024-04-25 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. diff --git a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/GA4GHClient.java b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/GA4GHClient.java index 5ec97c7c4dc..2959295e3a0 100644 --- a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/GA4GHClient.java +++ b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/GA4GHClient.java @@ -27,7 +27,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. -* Autogenerated on: 2024-04-17 +* Autogenerated on: 2024-04-25 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. diff --git a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/IndividualClient.java b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/IndividualClient.java index cbfba299f88..66f78beaf7e 100644 --- a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/IndividualClient.java +++ b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/IndividualClient.java @@ -36,7 +36,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. -* Autogenerated on: 2024-04-17 +* Autogenerated on: 2024-04-25 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. diff --git a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/JobClient.java b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/JobClient.java index 9ebea67f137..f34b38d60f6 100644 --- a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/JobClient.java +++ b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/JobClient.java @@ -37,7 +37,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. -* Autogenerated on: 2024-04-17 +* Autogenerated on: 2024-04-25 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. diff --git a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/MetaClient.java b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/MetaClient.java index 5f3e0ceef96..3d4dddbf928 100644 --- a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/MetaClient.java +++ b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/MetaClient.java @@ -28,7 +28,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. -* Autogenerated on: 2024-04-17 +* Autogenerated on: 2024-04-25 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. diff --git a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/ProjectClient.java b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/ProjectClient.java index fe6b3ab2206..8931d46d3c2 100644 --- a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/ProjectClient.java +++ b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/ProjectClient.java @@ -32,7 +32,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. -* Autogenerated on: 2024-04-17 +* Autogenerated on: 2024-04-25 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. diff --git a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/SampleClient.java b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/SampleClient.java index 17a8bf1b762..5de5d3488bd 100644 --- a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/SampleClient.java +++ b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/SampleClient.java @@ -36,7 +36,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. -* Autogenerated on: 2024-04-17 +* Autogenerated on: 2024-04-25 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. diff --git a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/StudyClient.java b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/StudyClient.java index e7aae483ca4..3f598c842a3 100644 --- a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/StudyClient.java +++ b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/StudyClient.java @@ -45,7 +45,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. -* Autogenerated on: 2024-04-17 +* Autogenerated on: 2024-04-25 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. diff --git a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/UserClient.java b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/UserClient.java index 503aed913b8..0ecdcb5b517 100644 --- a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/UserClient.java +++ b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/UserClient.java @@ -36,7 +36,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. -* Autogenerated on: 2024-04-17 +* Autogenerated on: 2024-04-25 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. diff --git a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/VariantClient.java b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/VariantClient.java index 3abdd8c4bec..810091d8275 100644 --- a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/VariantClient.java +++ b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/VariantClient.java @@ -62,7 +62,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. -* Autogenerated on: 2024-04-17 +* Autogenerated on: 2024-04-25 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. @@ -105,7 +105,7 @@ public VariantClient(String token, ClientConfiguration configuration) { * ct: List of SO consequence types, e.g. missense_variant,stop_lost or SO:0001583,SO:0001578. Accepts aliases 'loss_of_function' * and 'protein_altering'. * xref: List of any external reference, these can be genes, proteins or variants. Accepted IDs include HGNC, Ensembl genes, - * dbSNP, ClinVar, HPO, Cosmic, ... + * dbSNP, ClinVar, HPO, Cosmic, HGVS ... * biotype: List of biotypes, e.g. protein_coding. * proteinSubstitution: Protein substitution scores include SIFT and PolyPhen. You can query using the score * {protein_score}[<|>|<=|>=]{number} or the description {protein_score}[~=|=]{description} e.g. polyphen>0.1,sift=tolerant. @@ -152,7 +152,7 @@ public RestResponse metadataAnnotation(ObjectMap params) throws Clien /** * Query variant annotations from any saved versions. * @param params Map containing any of the following optional parameters. - * id: List of IDs, these can be rs IDs (dbSNP) or variants in the format chrom:start:ref:alt, e.g. rs116600158,19:7177679:C:T. + * id: List of variant IDs in the format chrom:start:ref:alt, e.g. 19:7177679:C:T. * region: List of regions, these can be just a single chromosome name or regions in the format chr:start-end, e.g.: * 2,3:100000-200000. * include: Fields included in the response, whole JSON path must be provided. @@ -640,7 +640,7 @@ public RestResponse runPlink(PlinkWrapperParams data, ObjectMap params) thr * approximateCountSamplingSize: Sampling size to get the approximate count. Larger values increase accuracy but also increase * execution time. * savedFilter: Use a saved filter at User level. - * id: List of IDs, these can be rs IDs (dbSNP) or variants in the format chrom:start:ref:alt, e.g. rs116600158,19:7177679:C:T. + * id: List of variant IDs in the format chrom:start:ref:alt, e.g. 19:7177679:C:T. * region: List of regions, these can be just a single chromosome name or regions in the format chr:start-end, e.g.: * 2,3:100000-200000. * type: List of types, accepted values are SNV, MNV, INDEL, SV, COPY_NUMBER, COPY_NUMBER_LOSS, COPY_NUMBER_GAIN, INSERTION, @@ -712,7 +712,7 @@ public RestResponse runPlink(PlinkWrapperParams data, ObjectMap params) thr * ct: List of SO consequence types, e.g. missense_variant,stop_lost or SO:0001583,SO:0001578. Accepts aliases 'loss_of_function' * and 'protein_altering'. * xref: List of any external reference, these can be genes, proteins or variants. Accepted IDs include HGNC, Ensembl genes, - * dbSNP, ClinVar, HPO, Cosmic, ... + * dbSNP, ClinVar, HPO, Cosmic, HGVS ... * biotype: List of biotypes, e.g. protein_coding. * proteinSubstitution: Protein substitution scores include SIFT and PolyPhen. You can query using the score * {protein_score}[<|>|<=|>=]{number} or the description {protein_score}[~=|=]{description} e.g. polyphen>0.1,sift=tolerant. diff --git a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/VariantOperationClient.java b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/VariantOperationClient.java index 0b210dc1dda..14a89e79d08 100644 --- a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/VariantOperationClient.java +++ b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/VariantOperationClient.java @@ -50,7 +50,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. -* Autogenerated on: 2024-04-17 +* Autogenerated on: 2024-04-25 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. diff --git a/opencga-client/src/main/javascript/Admin.js b/opencga-client/src/main/javascript/Admin.js index 492edb26ae9..5772c11289c 100644 --- a/opencga-client/src/main/javascript/Admin.js +++ b/opencga-client/src/main/javascript/Admin.js @@ -12,7 +12,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. - * Autogenerated on: 2024-04-17 + * Autogenerated on: 2024-04-25 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. diff --git a/opencga-client/src/main/javascript/Alignment.js b/opencga-client/src/main/javascript/Alignment.js index 88753f9f105..c6e95fac4a9 100644 --- a/opencga-client/src/main/javascript/Alignment.js +++ b/opencga-client/src/main/javascript/Alignment.js @@ -12,7 +12,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. - * Autogenerated on: 2024-04-17 + * Autogenerated on: 2024-04-25 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. diff --git a/opencga-client/src/main/javascript/ClinicalAnalysis.js b/opencga-client/src/main/javascript/ClinicalAnalysis.js index 6a3e8de727e..78c02c0920b 100644 --- a/opencga-client/src/main/javascript/ClinicalAnalysis.js +++ b/opencga-client/src/main/javascript/ClinicalAnalysis.js @@ -12,7 +12,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. - * Autogenerated on: 2024-04-17 + * Autogenerated on: 2024-04-25 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. @@ -585,8 +585,7 @@ export default class ClinicalAnalysis extends OpenCGAParentClass { * but also increase execution time. * @param {String} [params.savedFilter] - Use a saved filter at User level. * @param {String} [params.includeInterpretation] - Interpretation ID to include the fields related to this interpretation. - * @param {String} [params.id] - List of IDs, these can be rs IDs (dbSNP) or variants in the format chrom:start:ref:alt, e.g. - * rs116600158,19:7177679:C:T. + * @param {String} [params.id] - List of variant IDs in the format chrom:start:ref:alt, e.g. 19:7177679:C:T. * @param {String} [params.region] - List of regions, these can be just a single chromosome name or regions in the format chr:start-end, * e.g.: 2,3:100000-200000. * @param {String} [params.type] - List of types, accepted values are SNV, MNV, INDEL, SV, COPY_NUMBER, COPY_NUMBER_LOSS, @@ -638,7 +637,7 @@ export default class ClinicalAnalysis extends OpenCGAParentClass { * @param {String} [params.ct] - List of SO consequence types, e.g. missense_variant,stop_lost or SO:0001583,SO:0001578. Accepts aliases * 'loss_of_function' and 'protein_altering'. * @param {String} [params.xref] - List of any external reference, these can be genes, proteins or variants. Accepted IDs include HGNC, - * Ensembl genes, dbSNP, ClinVar, HPO, Cosmic, ... + * Ensembl genes, dbSNP, ClinVar, HPO, Cosmic, HGVS ... * @param {String} [params.biotype] - List of biotypes, e.g. protein_coding. * @param {String} [params.proteinSubstitution] - Protein substitution scores include SIFT and PolyPhen. You can query using the score * {protein_score}[<|>|<=|>=]{number} or the description {protein_score}[~=|=]{description} e.g. polyphen>0.1,sift=tolerant. diff --git a/opencga-client/src/main/javascript/Cohort.js b/opencga-client/src/main/javascript/Cohort.js index 813bde9476f..bc33d1c6e26 100644 --- a/opencga-client/src/main/javascript/Cohort.js +++ b/opencga-client/src/main/javascript/Cohort.js @@ -12,7 +12,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. - * Autogenerated on: 2024-04-17 + * Autogenerated on: 2024-04-25 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. diff --git a/opencga-client/src/main/javascript/DiseasePanel.js b/opencga-client/src/main/javascript/DiseasePanel.js index e78120b782e..c1f49cba7da 100644 --- a/opencga-client/src/main/javascript/DiseasePanel.js +++ b/opencga-client/src/main/javascript/DiseasePanel.js @@ -12,7 +12,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. - * Autogenerated on: 2024-04-17 + * Autogenerated on: 2024-04-25 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. diff --git a/opencga-client/src/main/javascript/Family.js b/opencga-client/src/main/javascript/Family.js index b445c29f5f4..9bd5d316764 100644 --- a/opencga-client/src/main/javascript/Family.js +++ b/opencga-client/src/main/javascript/Family.js @@ -12,7 +12,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. - * Autogenerated on: 2024-04-17 + * Autogenerated on: 2024-04-25 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. diff --git a/opencga-client/src/main/javascript/File.js b/opencga-client/src/main/javascript/File.js index 2aa945f22ce..c11712707b8 100644 --- a/opencga-client/src/main/javascript/File.js +++ b/opencga-client/src/main/javascript/File.js @@ -12,7 +12,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. - * Autogenerated on: 2024-04-17 + * Autogenerated on: 2024-04-25 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. diff --git a/opencga-client/src/main/javascript/GA4GH.js b/opencga-client/src/main/javascript/GA4GH.js index d1da328c363..c74108c5ca5 100644 --- a/opencga-client/src/main/javascript/GA4GH.js +++ b/opencga-client/src/main/javascript/GA4GH.js @@ -12,7 +12,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. - * Autogenerated on: 2024-04-17 + * Autogenerated on: 2024-04-25 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. diff --git a/opencga-client/src/main/javascript/Individual.js b/opencga-client/src/main/javascript/Individual.js index 94a4b3565f3..5ec331eeca4 100644 --- a/opencga-client/src/main/javascript/Individual.js +++ b/opencga-client/src/main/javascript/Individual.js @@ -12,7 +12,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. - * Autogenerated on: 2024-04-17 + * Autogenerated on: 2024-04-25 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. diff --git a/opencga-client/src/main/javascript/Job.js b/opencga-client/src/main/javascript/Job.js index 4fefa922553..67b8db8e091 100644 --- a/opencga-client/src/main/javascript/Job.js +++ b/opencga-client/src/main/javascript/Job.js @@ -12,7 +12,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. - * Autogenerated on: 2024-04-17 + * Autogenerated on: 2024-04-25 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. diff --git a/opencga-client/src/main/javascript/Meta.js b/opencga-client/src/main/javascript/Meta.js index da37ac584da..0cea26d1a89 100644 --- a/opencga-client/src/main/javascript/Meta.js +++ b/opencga-client/src/main/javascript/Meta.js @@ -12,7 +12,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. - * Autogenerated on: 2024-04-17 + * Autogenerated on: 2024-04-25 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. diff --git a/opencga-client/src/main/javascript/Project.js b/opencga-client/src/main/javascript/Project.js index 47c7ee63038..1afb1f8c793 100644 --- a/opencga-client/src/main/javascript/Project.js +++ b/opencga-client/src/main/javascript/Project.js @@ -12,7 +12,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. - * Autogenerated on: 2024-04-17 + * Autogenerated on: 2024-04-25 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. diff --git a/opencga-client/src/main/javascript/Sample.js b/opencga-client/src/main/javascript/Sample.js index ec2124cefa7..907ffe1b935 100644 --- a/opencga-client/src/main/javascript/Sample.js +++ b/opencga-client/src/main/javascript/Sample.js @@ -12,7 +12,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. - * Autogenerated on: 2024-04-17 + * Autogenerated on: 2024-04-25 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. diff --git a/opencga-client/src/main/javascript/Study.js b/opencga-client/src/main/javascript/Study.js index 0c75aa2f018..fed4b5a6c39 100644 --- a/opencga-client/src/main/javascript/Study.js +++ b/opencga-client/src/main/javascript/Study.js @@ -12,7 +12,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. - * Autogenerated on: 2024-04-17 + * Autogenerated on: 2024-04-25 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. diff --git a/opencga-client/src/main/javascript/User.js b/opencga-client/src/main/javascript/User.js index 23454b1aab1..8775caa0071 100644 --- a/opencga-client/src/main/javascript/User.js +++ b/opencga-client/src/main/javascript/User.js @@ -12,7 +12,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. - * Autogenerated on: 2024-04-17 + * Autogenerated on: 2024-04-25 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. diff --git a/opencga-client/src/main/javascript/Variant.js b/opencga-client/src/main/javascript/Variant.js index 1af0a7e0d34..ecfa45cd988 100644 --- a/opencga-client/src/main/javascript/Variant.js +++ b/opencga-client/src/main/javascript/Variant.js @@ -12,7 +12,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. - * Autogenerated on: 2024-04-17 + * Autogenerated on: 2024-04-25 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. @@ -57,7 +57,7 @@ export default class Variant extends OpenCGAParentClass { * @param {String} [params.ct] - List of SO consequence types, e.g. missense_variant,stop_lost or SO:0001583,SO:0001578. Accepts aliases * 'loss_of_function' and 'protein_altering'. * @param {String} [params.xref] - List of any external reference, these can be genes, proteins or variants. Accepted IDs include HGNC, - * Ensembl genes, dbSNP, ClinVar, HPO, Cosmic, ... + * Ensembl genes, dbSNP, ClinVar, HPO, Cosmic, HGVS ... * @param {String} [params.biotype] - List of biotypes, e.g. protein_coding. * @param {String} [params.proteinSubstitution] - Protein substitution scores include SIFT and PolyPhen. You can query using the score * {protein_score}[<|>|<=|>=]{number} or the description {protein_score}[~=|=]{description} e.g. polyphen>0.1,sift=tolerant. @@ -103,8 +103,7 @@ export default class Variant extends OpenCGAParentClass { /** Query variant annotations from any saved versions * @param {Object} [params] - The Object containing the following optional parameters: - * @param {String} [params.id] - List of IDs, these can be rs IDs (dbSNP) or variants in the format chrom:start:ref:alt, e.g. - * rs116600158,19:7177679:C:T. + * @param {String} [params.id] - List of variant IDs in the format chrom:start:ref:alt, e.g. 19:7177679:C:T. * @param {String} [params.region] - List of regions, these can be just a single chromosome name or regions in the format chr:start-end, * e.g.: 2,3:100000-200000. * @param {String} [params.include] - Fields included in the response, whole JSON path must be provided. @@ -519,8 +518,7 @@ export default class Variant extends OpenCGAParentClass { * @param {Number} [params.approximateCountSamplingSize] - Sampling size to get the approximate count. Larger values increase accuracy * but also increase execution time. * @param {String} [params.savedFilter] - Use a saved filter at User level. - * @param {String} [params.id] - List of IDs, these can be rs IDs (dbSNP) or variants in the format chrom:start:ref:alt, e.g. - * rs116600158,19:7177679:C:T. + * @param {String} [params.id] - List of variant IDs in the format chrom:start:ref:alt, e.g. 19:7177679:C:T. * @param {String} [params.region] - List of regions, these can be just a single chromosome name or regions in the format chr:start-end, * e.g.: 2,3:100000-200000. * @param {String} [params.type] - List of types, accepted values are SNV, MNV, INDEL, SV, COPY_NUMBER, COPY_NUMBER_LOSS, @@ -595,7 +593,7 @@ export default class Variant extends OpenCGAParentClass { * @param {String} [params.ct] - List of SO consequence types, e.g. missense_variant,stop_lost or SO:0001583,SO:0001578. Accepts aliases * 'loss_of_function' and 'protein_altering'. * @param {String} [params.xref] - List of any external reference, these can be genes, proteins or variants. Accepted IDs include HGNC, - * Ensembl genes, dbSNP, ClinVar, HPO, Cosmic, ... + * Ensembl genes, dbSNP, ClinVar, HPO, Cosmic, HGVS ... * @param {String} [params.biotype] - List of biotypes, e.g. protein_coding. * @param {String} [params.proteinSubstitution] - Protein substitution scores include SIFT and PolyPhen. You can query using the score * {protein_score}[<|>|<=|>=]{number} or the description {protein_score}[~=|=]{description} e.g. polyphen>0.1,sift=tolerant. diff --git a/opencga-client/src/main/javascript/VariantOperation.js b/opencga-client/src/main/javascript/VariantOperation.js index 66f185b9172..89b31d6f794 100644 --- a/opencga-client/src/main/javascript/VariantOperation.js +++ b/opencga-client/src/main/javascript/VariantOperation.js @@ -12,7 +12,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. - * Autogenerated on: 2024-04-17 + * Autogenerated on: 2024-04-25 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. diff --git a/opencga-client/src/main/python/pyopencga/rest_clients/admin_client.py b/opencga-client/src/main/python/pyopencga/rest_clients/admin_client.py index e858d7c2cb4..cf56a794019 100644 --- a/opencga-client/src/main/python/pyopencga/rest_clients/admin_client.py +++ b/opencga-client/src/main/python/pyopencga/rest_clients/admin_client.py @@ -2,7 +2,7 @@ WARNING: AUTOGENERATED CODE This code was generated by a tool. - Autogenerated on: 2024-04-17 + Autogenerated on: 2024-04-25 Manual changes to this file may cause unexpected behavior in your application. Manual changes to this file will be overwritten if the code is regenerated. diff --git a/opencga-client/src/main/python/pyopencga/rest_clients/alignment_client.py b/opencga-client/src/main/python/pyopencga/rest_clients/alignment_client.py index 70672d7a91c..c61107c6533 100644 --- a/opencga-client/src/main/python/pyopencga/rest_clients/alignment_client.py +++ b/opencga-client/src/main/python/pyopencga/rest_clients/alignment_client.py @@ -2,7 +2,7 @@ WARNING: AUTOGENERATED CODE This code was generated by a tool. - Autogenerated on: 2024-04-17 + Autogenerated on: 2024-04-25 Manual changes to this file may cause unexpected behavior in your application. Manual changes to this file will be overwritten if the code is regenerated. diff --git a/opencga-client/src/main/python/pyopencga/rest_clients/clinical_analysis_client.py b/opencga-client/src/main/python/pyopencga/rest_clients/clinical_analysis_client.py index f6081dc1c88..eacad69006d 100644 --- a/opencga-client/src/main/python/pyopencga/rest_clients/clinical_analysis_client.py +++ b/opencga-client/src/main/python/pyopencga/rest_clients/clinical_analysis_client.py @@ -2,7 +2,7 @@ WARNING: AUTOGENERATED CODE This code was generated by a tool. - Autogenerated on: 2024-04-17 + Autogenerated on: 2024-04-25 Manual changes to this file may cause unexpected behavior in your application. Manual changes to this file will be overwritten if the code is regenerated. @@ -713,8 +713,8 @@ def query_variant(self, **options): :param str saved_filter: Use a saved filter at User level. :param str include_interpretation: Interpretation ID to include the fields related to this interpretation. - :param str id: List of IDs, these can be rs IDs (dbSNP) or variants in - the format chrom:start:ref:alt, e.g. rs116600158,19:7177679:C:T. + :param str id: List of variant IDs in the format chrom:start:ref:alt, + e.g. 19:7177679:C:T. :param str region: List of regions, these can be just a single chromosome name or regions in the format chr:start-end, e.g.: 2,3:100000-200000. @@ -800,7 +800,7 @@ def query_variant(self, **options): aliases 'loss_of_function' and 'protein_altering'. :param str xref: List of any external reference, these can be genes, proteins or variants. Accepted IDs include HGNC, Ensembl genes, - dbSNP, ClinVar, HPO, Cosmic, ... + dbSNP, ClinVar, HPO, Cosmic, HGVS ... :param str biotype: List of biotypes, e.g. protein_coding. :param str protein_substitution: Protein substitution scores include SIFT and PolyPhen. You can query using the score diff --git a/opencga-client/src/main/python/pyopencga/rest_clients/cohort_client.py b/opencga-client/src/main/python/pyopencga/rest_clients/cohort_client.py index 22522d3080d..e4ecc0c8ece 100644 --- a/opencga-client/src/main/python/pyopencga/rest_clients/cohort_client.py +++ b/opencga-client/src/main/python/pyopencga/rest_clients/cohort_client.py @@ -2,7 +2,7 @@ WARNING: AUTOGENERATED CODE This code was generated by a tool. - Autogenerated on: 2024-04-17 + Autogenerated on: 2024-04-25 Manual changes to this file may cause unexpected behavior in your application. Manual changes to this file will be overwritten if the code is regenerated. diff --git a/opencga-client/src/main/python/pyopencga/rest_clients/disease_panel_client.py b/opencga-client/src/main/python/pyopencga/rest_clients/disease_panel_client.py index 4d745af3e36..77d939aa32e 100644 --- a/opencga-client/src/main/python/pyopencga/rest_clients/disease_panel_client.py +++ b/opencga-client/src/main/python/pyopencga/rest_clients/disease_panel_client.py @@ -2,7 +2,7 @@ WARNING: AUTOGENERATED CODE This code was generated by a tool. - Autogenerated on: 2024-04-17 + Autogenerated on: 2024-04-25 Manual changes to this file may cause unexpected behavior in your application. Manual changes to this file will be overwritten if the code is regenerated. diff --git a/opencga-client/src/main/python/pyopencga/rest_clients/family_client.py b/opencga-client/src/main/python/pyopencga/rest_clients/family_client.py index 5d2a725b8ca..82d22a7a3f0 100644 --- a/opencga-client/src/main/python/pyopencga/rest_clients/family_client.py +++ b/opencga-client/src/main/python/pyopencga/rest_clients/family_client.py @@ -2,7 +2,7 @@ WARNING: AUTOGENERATED CODE This code was generated by a tool. - Autogenerated on: 2024-04-17 + Autogenerated on: 2024-04-25 Manual changes to this file may cause unexpected behavior in your application. Manual changes to this file will be overwritten if the code is regenerated. diff --git a/opencga-client/src/main/python/pyopencga/rest_clients/file_client.py b/opencga-client/src/main/python/pyopencga/rest_clients/file_client.py index 982e768b914..61a4f098c06 100644 --- a/opencga-client/src/main/python/pyopencga/rest_clients/file_client.py +++ b/opencga-client/src/main/python/pyopencga/rest_clients/file_client.py @@ -2,7 +2,7 @@ WARNING: AUTOGENERATED CODE This code was generated by a tool. - Autogenerated on: 2024-04-17 + Autogenerated on: 2024-04-25 Manual changes to this file may cause unexpected behavior in your application. Manual changes to this file will be overwritten if the code is regenerated. diff --git a/opencga-client/src/main/python/pyopencga/rest_clients/ga4gh_client.py b/opencga-client/src/main/python/pyopencga/rest_clients/ga4gh_client.py index d474c8e4742..759d188fd17 100644 --- a/opencga-client/src/main/python/pyopencga/rest_clients/ga4gh_client.py +++ b/opencga-client/src/main/python/pyopencga/rest_clients/ga4gh_client.py @@ -2,7 +2,7 @@ WARNING: AUTOGENERATED CODE This code was generated by a tool. - Autogenerated on: 2024-04-17 + Autogenerated on: 2024-04-25 Manual changes to this file may cause unexpected behavior in your application. Manual changes to this file will be overwritten if the code is regenerated. diff --git a/opencga-client/src/main/python/pyopencga/rest_clients/individual_client.py b/opencga-client/src/main/python/pyopencga/rest_clients/individual_client.py index 0ad324b569d..b4abe50abc8 100644 --- a/opencga-client/src/main/python/pyopencga/rest_clients/individual_client.py +++ b/opencga-client/src/main/python/pyopencga/rest_clients/individual_client.py @@ -2,7 +2,7 @@ WARNING: AUTOGENERATED CODE This code was generated by a tool. - Autogenerated on: 2024-04-17 + Autogenerated on: 2024-04-25 Manual changes to this file may cause unexpected behavior in your application. Manual changes to this file will be overwritten if the code is regenerated. diff --git a/opencga-client/src/main/python/pyopencga/rest_clients/job_client.py b/opencga-client/src/main/python/pyopencga/rest_clients/job_client.py index 4530c66f33f..278d1595159 100644 --- a/opencga-client/src/main/python/pyopencga/rest_clients/job_client.py +++ b/opencga-client/src/main/python/pyopencga/rest_clients/job_client.py @@ -2,7 +2,7 @@ WARNING: AUTOGENERATED CODE This code was generated by a tool. - Autogenerated on: 2024-04-17 + Autogenerated on: 2024-04-25 Manual changes to this file may cause unexpected behavior in your application. Manual changes to this file will be overwritten if the code is regenerated. diff --git a/opencga-client/src/main/python/pyopencga/rest_clients/meta_client.py b/opencga-client/src/main/python/pyopencga/rest_clients/meta_client.py index 617d13cd022..c5beeb4d320 100644 --- a/opencga-client/src/main/python/pyopencga/rest_clients/meta_client.py +++ b/opencga-client/src/main/python/pyopencga/rest_clients/meta_client.py @@ -2,7 +2,7 @@ WARNING: AUTOGENERATED CODE This code was generated by a tool. - Autogenerated on: 2024-04-17 + Autogenerated on: 2024-04-25 Manual changes to this file may cause unexpected behavior in your application. Manual changes to this file will be overwritten if the code is regenerated. diff --git a/opencga-client/src/main/python/pyopencga/rest_clients/project_client.py b/opencga-client/src/main/python/pyopencga/rest_clients/project_client.py index 80e1be2620d..1fc03169013 100644 --- a/opencga-client/src/main/python/pyopencga/rest_clients/project_client.py +++ b/opencga-client/src/main/python/pyopencga/rest_clients/project_client.py @@ -2,7 +2,7 @@ WARNING: AUTOGENERATED CODE This code was generated by a tool. - Autogenerated on: 2024-04-17 + Autogenerated on: 2024-04-25 Manual changes to this file may cause unexpected behavior in your application. Manual changes to this file will be overwritten if the code is regenerated. diff --git a/opencga-client/src/main/python/pyopencga/rest_clients/sample_client.py b/opencga-client/src/main/python/pyopencga/rest_clients/sample_client.py index bd2bb71476c..ff401a57af2 100644 --- a/opencga-client/src/main/python/pyopencga/rest_clients/sample_client.py +++ b/opencga-client/src/main/python/pyopencga/rest_clients/sample_client.py @@ -2,7 +2,7 @@ WARNING: AUTOGENERATED CODE This code was generated by a tool. - Autogenerated on: 2024-04-17 + Autogenerated on: 2024-04-25 Manual changes to this file may cause unexpected behavior in your application. Manual changes to this file will be overwritten if the code is regenerated. diff --git a/opencga-client/src/main/python/pyopencga/rest_clients/study_client.py b/opencga-client/src/main/python/pyopencga/rest_clients/study_client.py index 64f9f0b38f4..9c6c7610d38 100644 --- a/opencga-client/src/main/python/pyopencga/rest_clients/study_client.py +++ b/opencga-client/src/main/python/pyopencga/rest_clients/study_client.py @@ -2,7 +2,7 @@ WARNING: AUTOGENERATED CODE This code was generated by a tool. - Autogenerated on: 2024-04-17 + Autogenerated on: 2024-04-25 Manual changes to this file may cause unexpected behavior in your application. Manual changes to this file will be overwritten if the code is regenerated. diff --git a/opencga-client/src/main/python/pyopencga/rest_clients/user_client.py b/opencga-client/src/main/python/pyopencga/rest_clients/user_client.py index 099919118b7..654bd1e6b9e 100644 --- a/opencga-client/src/main/python/pyopencga/rest_clients/user_client.py +++ b/opencga-client/src/main/python/pyopencga/rest_clients/user_client.py @@ -2,7 +2,7 @@ WARNING: AUTOGENERATED CODE This code was generated by a tool. - Autogenerated on: 2024-04-17 + Autogenerated on: 2024-04-25 Manual changes to this file may cause unexpected behavior in your application. Manual changes to this file will be overwritten if the code is regenerated. diff --git a/opencga-client/src/main/python/pyopencga/rest_clients/variant_client.py b/opencga-client/src/main/python/pyopencga/rest_clients/variant_client.py index 89f1c3d162e..86e1f537ba4 100644 --- a/opencga-client/src/main/python/pyopencga/rest_clients/variant_client.py +++ b/opencga-client/src/main/python/pyopencga/rest_clients/variant_client.py @@ -2,7 +2,7 @@ WARNING: AUTOGENERATED CODE This code was generated by a tool. - Autogenerated on: 2024-04-17 + Autogenerated on: 2024-04-25 Manual changes to this file may cause unexpected behavior in your application. Manual changes to this file will be overwritten if the code is regenerated. @@ -65,7 +65,7 @@ def aggregation_stats(self, **options): aliases 'loss_of_function' and 'protein_altering'. :param str xref: List of any external reference, these can be genes, proteins or variants. Accepted IDs include HGNC, Ensembl genes, - dbSNP, ClinVar, HPO, Cosmic, ... + dbSNP, ClinVar, HPO, Cosmic, HGVS ... :param str biotype: List of biotypes, e.g. protein_coding. :param str protein_substitution: Protein substitution scores include SIFT and PolyPhen. You can query using the score @@ -126,8 +126,8 @@ def query_annotation(self, **options): Query variant annotations from any saved versions. PATH: /{apiVersion}/analysis/variant/annotation/query - :param str id: List of IDs, these can be rs IDs (dbSNP) or variants in - the format chrom:start:ref:alt, e.g. rs116600158,19:7177679:C:T. + :param str id: List of variant IDs in the format chrom:start:ref:alt, + e.g. 19:7177679:C:T. :param str region: List of regions, these can be just a single chromosome name or regions in the format chr:start-end, e.g.: 2,3:100000-200000. @@ -661,8 +661,8 @@ def query(self, **options): approximate count. Larger values increase accuracy but also increase execution time. :param str saved_filter: Use a saved filter at User level. - :param str id: List of IDs, these can be rs IDs (dbSNP) or variants in - the format chrom:start:ref:alt, e.g. rs116600158,19:7177679:C:T. + :param str id: List of variant IDs in the format chrom:start:ref:alt, + e.g. 19:7177679:C:T. :param str region: List of regions, these can be just a single chromosome name or regions in the format chr:start-end, e.g.: 2,3:100000-200000. @@ -787,7 +787,7 @@ def query(self, **options): aliases 'loss_of_function' and 'protein_altering'. :param str xref: List of any external reference, these can be genes, proteins or variants. Accepted IDs include HGNC, Ensembl genes, - dbSNP, ClinVar, HPO, Cosmic, ... + dbSNP, ClinVar, HPO, Cosmic, HGVS ... :param str biotype: List of biotypes, e.g. protein_coding. :param str protein_substitution: Protein substitution scores include SIFT and PolyPhen. You can query using the score diff --git a/opencga-client/src/main/python/pyopencga/rest_clients/variant_operation_client.py b/opencga-client/src/main/python/pyopencga/rest_clients/variant_operation_client.py index f53a2ace921..a98de91c73a 100644 --- a/opencga-client/src/main/python/pyopencga/rest_clients/variant_operation_client.py +++ b/opencga-client/src/main/python/pyopencga/rest_clients/variant_operation_client.py @@ -2,7 +2,7 @@ WARNING: AUTOGENERATED CODE This code was generated by a tool. - Autogenerated on: 2024-04-17 + Autogenerated on: 2024-04-25 Manual changes to this file may cause unexpected behavior in your application. Manual changes to this file will be overwritten if the code is regenerated. From e4fac8aeb68db930f87cc547c2ee770000ee3928 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joaqu=C3=ADn=20T=C3=A1rraga=20Gim=C3=A9nez?= Date: Thu, 25 Apr 2024 15:29:52 +0200 Subject: [PATCH 36/85] analysis: fix JUnit test, TASK-6117 --- .../opencga/analysis/variant/manager/VariantOperationsTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/opencga-analysis/src/test/java/org/opencb/opencga/analysis/variant/manager/VariantOperationsTest.java b/opencga-analysis/src/test/java/org/opencb/opencga/analysis/variant/manager/VariantOperationsTest.java index 14c09547876..f9a698b2fc9 100644 --- a/opencga-analysis/src/test/java/org/opencb/opencga/analysis/variant/manager/VariantOperationsTest.java +++ b/opencga-analysis/src/test/java/org/opencb/opencga/analysis/variant/manager/VariantOperationsTest.java @@ -515,7 +515,7 @@ public void testCellbaseConfigure() throws Exception { assertEquals("GRCh38", cellBaseUtils.getAssembly()); String newCellbase = "https://uk.ws.zettagenomics.com/cellbase/"; - String newCellbaseVersion = "v5.2"; + String newCellbaseVersion = "v5.8"; assertNotEquals(newCellbase, cellBaseUtils.getURL()); assertNotEquals(newCellbaseVersion, cellBaseUtils.getVersion()); From b61bf0967026cc648103fefd2e50c4cd51d15f60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacobo=20Coll=20Morag=C3=B3n?= Date: Fri, 26 Apr 2024 14:05:10 +0100 Subject: [PATCH 37/85] storage: Avoid concurrent variant-index jobs of files sharing samples. #TASK-6078 --- .../VariantStorageMetadataManager.java | 79 +++-- .../core/metadata/models/TaskMetadata.java | 27 +- .../core/variant/VariantStorageEngine.java | 79 +++-- .../dummy/DummyStudyMetadataDBAdaptor.java | 2 +- ...HadoopLocalLoadVariantStoragePipeline.java | 26 +- .../variant/HadoopVariantStorageEngine.java | 5 + .../metadata/HBaseTaskMetadataDBAdaptor.java | 2 +- ...doopVariantStorageEngineSplitDataTest.java | 283 ++++++++++++++++++ .../hadoop/variant/VariantHbaseTestUtils.java | 9 +- 9 files changed, 441 insertions(+), 71 deletions(-) diff --git a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/metadata/VariantStorageMetadataManager.java b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/metadata/VariantStorageMetadataManager.java index cf4477bb4f1..ce192dade2b 100644 --- a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/metadata/VariantStorageMetadataManager.java +++ b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/metadata/VariantStorageMetadataManager.java @@ -1273,13 +1273,17 @@ public TaskMetadata getTask(int studyId, String taskName, List fileIds) } public Iterator taskIterator(int studyId) { - return taskIterator(studyId, null); + return taskIterator(studyId, null, false); } public Iterator taskIterator(int studyId, List statusFilter) { return taskIterator(studyId, statusFilter, false); } + public Iterator taskIterator(int studyId, TaskMetadata.Status... statusFilter) { + return taskIterator(studyId, Arrays.asList(statusFilter), false); + } + public Iterator taskIterator(int studyId, List statusFilter, boolean reversed) { return taskDBAdaptor.taskIterator(studyId, statusFilter, reversed); } @@ -1288,6 +1292,13 @@ public Iterable getRunningTasks(int studyId) { return taskDBAdaptor.getRunningTasks(studyId); } + public Iterable getActiveTasks(int studyId) { + return () -> taskIterator(studyId, + TaskMetadata.Status.RUNNING, + TaskMetadata.Status.DONE, + TaskMetadata.Status.ERROR); + } + public void unsecureUpdateTask(int studyId, TaskMetadata task) throws StorageEngineException { task.setStudyId(studyId); if (task.getId() == 0) { @@ -2074,47 +2085,35 @@ private TaskMetadata getRunningTaskCompatibleOrFail(int studyId, String jobOpera TaskMetadata.Type type, Predicate allowConcurrent) throws StorageEngineException { TaskMetadata resumeTask = null; - Iterator iterator = taskIterator(studyId, Arrays.asList( - TaskMetadata.Status.DONE, - TaskMetadata.Status.RUNNING, - TaskMetadata.Status.ERROR)); - while (iterator.hasNext()) { - TaskMetadata task = iterator.next(); + for (TaskMetadata task : getActiveTasks(studyId)) { TaskMetadata.Status currentStatus = task.currentStatus(); - switch (currentStatus) { - case READY: - logger.warn("Unexpected READY task. IGNORE"); - // Ignore ready operations - break; - case DONE: - case RUNNING: - if (!resume) { - if (task.sameOperation(fileIds, type, jobOperationName)) { - throw StorageEngineException.currentOperationInProgressException(task, this); - } else { - if (allowConcurrent.test(task)) { - break; - } else { - throw StorageEngineException.otherOperationInProgressException(task, jobOperationName, fileIds, this); - } - } - } - // DO NOT BREAK!. Resuming last loading, go to error case. - case ERROR: - if (!task.sameOperation(fileIds, type, jobOperationName)) { - if (allowConcurrent.test(task)) { - break; - } else { - throw StorageEngineException.otherOperationInProgressException(task, jobOperationName, fileIds, this, resume); - } - } else { - logger.info("Resuming last batch operation \"" + task.getName() + "\" due to error."); - resumeTask = task; - } - break; - default: - throw new IllegalArgumentException("Unknown Status " + currentStatus); + if (currentStatus != TaskMetadata.Status.DONE + && currentStatus != TaskMetadata.Status.RUNNING + && currentStatus != TaskMetadata.Status.ERROR) { + logger.warn("Unexpected {} task. IGNORE", currentStatus); + // Ignore ready operations + continue; + } + + if (task.sameOperation(fileIds, type, jobOperationName)) { + if (currentStatus == TaskMetadata.Status.ERROR) { + // Automatically resume ERROR status tasks + logger.info("Resuming last batch operation \"" + task.getName() + "\" due to error."); + resumeTask = task; + } else if (resume) { + // Force resume + logger.info("Manually resuming last batch operation \"" + task.getName() + "\" in status " + currentStatus + "."); + resumeTask = task; + } else { + // Already being executed + throw StorageEngineException.currentOperationInProgressException(task, this); + } + } else { + // Check if it can be executed concurrently + if (!allowConcurrent.test(task)) { + throw StorageEngineException.otherOperationInProgressException(task, jobOperationName, fileIds, this); + } } } return resumeTask; diff --git a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/metadata/models/TaskMetadata.java b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/metadata/models/TaskMetadata.java index e7d32e12b5d..aba5d230c88 100644 --- a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/metadata/models/TaskMetadata.java +++ b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/metadata/models/TaskMetadata.java @@ -34,10 +34,33 @@ public class TaskMetadata { public enum Status { NONE, + /** + * Active task. + * Running, but not finished + */ RUNNING, - DONE, // Finished, but some work still needed (optional) + /** + * Active task. + * Finished, but some work still needed (optional status) + */ + DONE, + /** + * Active task. + * Currently, paused. + * Errors found during the execution. Needs to be resumed or cleaned. + */ + ERROR, + /** + * Finished. + * Ready to be used + */ READY, - ERROR + /** + * Finished. + * Task was aborted, cancelled or rolled back. + * Any needed clean might be executed by other running tasks + */ + ABORTED, } public enum Type { diff --git a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/VariantStorageEngine.java b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/VariantStorageEngine.java index 018d09292f1..8368fcf7074 100644 --- a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/VariantStorageEngine.java +++ b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/VariantStorageEngine.java @@ -946,35 +946,78 @@ public void removeSamples(String study, List samples, URI outdir) throws */ protected TaskMetadata preRemove(String study, List files, List samples) throws StorageEngineException { AtomicReference batchFileOperation = new AtomicReference<>(); + boolean force = getOptions().getBoolean(FORCE.key(), FORCE.defaultValue()); + boolean resume = getOptions().getBoolean(RESUME.key(), RESUME.defaultValue()); VariantStorageMetadataManager metadataManager = getMetadataManager(); - metadataManager.updateStudyMetadata(study, studyMetadata -> { - List fileIds = new ArrayList<>(files.size()); - for (String file : files) { - FileMetadata fileMetadata = metadataManager.getFileMetadata(studyMetadata.getId(), file); - if (fileMetadata == null) { - throw VariantQueryException.fileNotFound(file, study); - } - if (fileMetadata.getType() == FileMetadata.Type.PARTIAL) { - String virtualFileName = metadataManager.getFileName( - studyMetadata.getId(), - fileMetadata.getAttributes().getInt(FileMetadata.VIRTUAL_PARENT)); - throw new StorageEngineException("Unable to remove " + FileMetadata.Type.PARTIAL + " file. " - + "Try removing its virtual file : '" + virtualFileName + "'"); - } - fileIds.add(fileMetadata.getId()); - if (!fileMetadata.isIndexed()) { + + int studyId = metadataManager.getStudyId(study); + List fileIds = new ArrayList<>(files.size()); + for (String file : files) { + FileMetadata fileMetadata = metadataManager.getFileMetadata(studyId, file); + if (fileMetadata == null) { + throw VariantQueryException.fileNotFound(file, study); + } + if (fileMetadata.getType() == FileMetadata.Type.PARTIAL) { + String virtualFileName = metadataManager.getFileName( + studyId, + fileMetadata.getAttributes().getInt(FileMetadata.VIRTUAL_PARENT)); + throw new StorageEngineException("Unable to remove " + FileMetadata.Type.PARTIAL + " file. " + + "Try removing its virtual file : '" + virtualFileName + "'"); + } + if (fileMetadata.getIndexStatus() == TaskMetadata.Status.NONE) { + if (force) { + logger.info("Force remove. Removing non indexed file: " + fileMetadata.getName()); + } else { throw new StorageEngineException("Unable to remove non indexed file: " + fileMetadata.getName()); } } + if (fileMetadata.getIndexStatus() == TaskMetadata.Status.RUNNING) { + if (force) { + logger.info("Force remove. Removing file while being indexed: " + fileMetadata.getName()); + } else { + throw new StorageEngineException("Unable to remove file while being indexed: " + fileMetadata.getName()); + } + } + fileIds.add(fileMetadata.getId()); + } - boolean resume = getOptions().getBoolean(RESUME.key(), RESUME.defaultValue()); + metadataManager.updateStudyMetadata(study, studyMetadata -> { + List tasksToAbort = new ArrayList<>(); + HashSet fileIdsSet = new HashSet<>(fileIds); batchFileOperation.set(metadataManager.addRunningTask( studyMetadata.getId(), REMOVE_OPERATION_NAME, fileIds, resume, - TaskMetadata.Type.REMOVE)); + TaskMetadata.Type.REMOVE, runningTask -> { + if (runningTask.getType() == TaskMetadata.Type.LOAD) { + if (force && fileIdsSet.containsAll(runningTask.getFileIds())) { + // Abort running load task as all files are being removed + tasksToAbort.add(runningTask); + return true; + } else { + if (force) { + logger.error("Unable to force remove the file while other files are being loaded."); + } + // Unable to remove files. Other files are being loaded. + return false; + } + } else { + // Unable to remove files. Other tasks are running. + return false; + } + })); + // If the task was successfully created, abort other tasks. + for (TaskMetadata task : tasksToAbort) { + List fileNames = task.getFileIds().stream() + .map(fileId -> metadataManager.getFileName(studyMetadata.getId(), fileId)) + .collect(Collectors.toList()); + TaskMetadata.Status status = TaskMetadata.Status.ABORTED; + logger.info("Force remove. Setting status to " + status + " of running task " + + task.getName() + "('id=" + task.getId() + ") for files " + fileNames); + metadataManager.setStatus(studyMetadata.getId(), task.getId(), status); + } return studyMetadata; }); diff --git a/opencga-storage/opencga-storage-core/src/test/java/org/opencb/opencga/storage/core/variant/dummy/DummyStudyMetadataDBAdaptor.java b/opencga-storage/opencga-storage-core/src/test/java/org/opencb/opencga/storage/core/variant/dummy/DummyStudyMetadataDBAdaptor.java index f954026b234..3d519030b19 100644 --- a/opencga-storage/opencga-storage-core/src/test/java/org/opencb/opencga/storage/core/variant/dummy/DummyStudyMetadataDBAdaptor.java +++ b/opencga-storage/opencga-storage-core/src/test/java/org/opencb/opencga/storage/core/variant/dummy/DummyStudyMetadataDBAdaptor.java @@ -222,7 +222,7 @@ public Iterator taskIterator(int studyId, List loadedGenotypes; private int sampleIndexVersion; @@ -182,19 +182,33 @@ protected void securePreLoad(StudyMetadata studyMetadata, VariantFileMetadata fi final AtomicInteger ongoingLoads = new AtomicInteger(1); // this boolean resume = options.getBoolean(VariantStorageOptions.RESUME.key(), VariantStorageOptions.RESUME.defaultValue()); - List fileIds = Collections.singletonList(getFileId()); - taskId = getMetadataManager() - .addRunningTask(studyId, OPERATION_NAME, fileIds, resume, Type.LOAD, + VariantStorageMetadataManager metadataManager = getMetadataManager(); + LinkedHashSet sampleIdsFromFileId = metadataManager.getSampleIdsFromFileId(studyId, getFileId()); + VariantStorageEngine.SplitData splitData = VariantStorageEngine.SplitData.from(options); + + taskId = metadataManager + .addRunningTask(studyId, OPERATION_NAME, Collections.singletonList(getFileId()), resume, Type.LOAD, operation -> { if (operation.getName().equals(OPERATION_NAME)) { - if (operation.currentStatus().equals(Status.ERROR)) { + if (operation.currentStatus() == Status.ERROR) { Integer fileId = operation.getFileIds().get(0); - String fileName = getMetadataManager().getFileName(studyMetadata.getId(), fileId); + String fileName = metadataManager.getFileName(studyMetadata.getId(), fileId); logger.warn("Pending load operation for file " + fileName + " (" + fileId + ')'); } else { ongoingLoads.incrementAndGet(); } + if (splitData != VariantStorageEngine.SplitData.CHROMOSOME && splitData != VariantStorageEngine.SplitData.REGION) { + // Do not allow any concurrent load operation on files sharing samples + for (Integer fileId : operation.getFileIds()) { + Set samples = metadataManager.getSampleIdsFromFileId(studyId, fileId); + for (Integer sample : samples) { + if (sampleIdsFromFileId.contains(sample)) { + return false; + } + } + } + } return true; } else { return false; diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/HadoopVariantStorageEngine.java b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/HadoopVariantStorageEngine.java index 2f0f6143b6b..afd6b54490e 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/HadoopVariantStorageEngine.java +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/HadoopVariantStorageEngine.java @@ -698,6 +698,11 @@ public void removeSamples(String study, List samples, URI outdir) throws remove(study, fullyDeletedFiles, samples, outdir); } + @Override + protected TaskMetadata preRemove(String study, List files, List samples) throws StorageEngineException { + return super.preRemove(study, files, samples); + } + @Override public void removeFiles(String study, List files, URI outdir) throws StorageEngineException { remove(study, files, Collections.emptyList(), outdir); diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/metadata/HBaseTaskMetadataDBAdaptor.java b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/metadata/HBaseTaskMetadataDBAdaptor.java index 290f937631b..4fe8d236cc1 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/metadata/HBaseTaskMetadataDBAdaptor.java +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/metadata/HBaseTaskMetadataDBAdaptor.java @@ -28,7 +28,7 @@ public TaskMetadata getTask(int studyId, int taskId, Long timeStamp) { @Override public Iterator taskIterator(int studyId, List statusFilter, boolean reversed) { - if (statusFilter == null) { + if (statusFilter == null || statusFilter.isEmpty()) { return iterator(getTaskRowKeyPrefix(studyId), TaskMetadata.class, reversed); } else if (statusFilter.contains(TaskMetadata.Status.READY)) { EnumSet set = EnumSet.copyOf(statusFilter); diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/test/java/org/opencb/opencga/storage/hadoop/variant/HadoopVariantStorageEngineSplitDataTest.java b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/test/java/org/opencb/opencga/storage/hadoop/variant/HadoopVariantStorageEngineSplitDataTest.java index f5ebbbe8fd6..c8bd80e1882 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/test/java/org/opencb/opencga/storage/hadoop/variant/HadoopVariantStorageEngineSplitDataTest.java +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/test/java/org/opencb/opencga/storage/hadoop/variant/HadoopVariantStorageEngineSplitDataTest.java @@ -2,8 +2,11 @@ import htsjdk.variant.vcf.VCFConstants; import org.apache.commons.lang3.StringUtils; +import org.hamcrest.CoreMatchers; +import org.hamcrest.MatcherAssert; import org.junit.*; import org.junit.experimental.categories.Category; +import org.mockito.Mockito; import org.opencb.biodata.models.variant.StudyEntry; import org.opencb.biodata.models.variant.Variant; import org.opencb.biodata.models.variant.avro.FileEntry; @@ -24,6 +27,7 @@ import org.opencb.opencga.storage.core.variant.VariantStorageBaseTest; import org.opencb.opencga.storage.core.variant.VariantStorageEngine; import org.opencb.opencga.storage.core.variant.VariantStorageOptions; +import org.opencb.opencga.storage.core.variant.VariantStoragePipeline; import org.opencb.opencga.storage.core.variant.adaptors.VariantField; import org.opencb.opencga.storage.core.variant.adaptors.VariantQuery; import org.opencb.opencga.storage.core.variant.adaptors.VariantQueryParam; @@ -50,6 +54,7 @@ public class HadoopVariantStorageEngineSplitDataTest extends VariantStorageBaseTest implements HadoopVariantStorageTest { public static final List SAMPLES = Arrays.asList("NA19600", "NA19660", "NA19661", "NA19685"); + public static final String MOCKED_EXCEPTION = "Mocked exception"; @ClassRule public static HadoopExternalResource externalResource = new HadoopExternalResource(); @@ -63,6 +68,91 @@ public void tearDown() throws Exception { VariantHbaseTestUtils.printVariants(getVariantStorageEngine().getDBAdaptor(), newOutputUri(getTestName().getMethodName())); } + @Test + public void testMultiChromosomeSplitDataConcurrentFail() throws Exception { + variantStorageEngine.getOptions().put(VariantStorageOptions.STUDY.key(), STUDY_NAME); + failAtLoadingFile("by_chr/", "chr20.variant-test-file.vcf.gz", outputUri); + // Will fail if LOAD_SPLIT_DATA is not set + thrown.expect(StoragePipelineException.class); + variantStorageEngine.index(Collections.singletonList(getResourceUri("by_chr/chr21.variant-test-file.vcf.gz")), outputUri); + } + + @Test + public void testMultiChromosomeSplitDataConcurrentFailOneIndexOther() throws Exception { + // Test goal: + // - Index chr20 and chr21 concurrently with shared samples and LOAD_SPLIT_DATA=CHROMOSOME + // Test steps: + // - Fail at loading chr20 (left the file in status "RUNNING") + // - Index chr21 correctly with LOAD_SPLIT_DATA=CHROMOSOME + + variantStorageEngine.getOptions().put(VariantStorageOptions.STUDY.key(), STUDY_NAME); + failAtLoadingFile("by_chr/", "chr20.variant-test-file.vcf.gz", outputUri); + + // Won't fail if LOAD_SPLIT_DATA is set correctly + variantStorageEngine.getOptions().put(VariantStorageOptions.LOAD_SPLIT_DATA.key(), VariantStorageEngine.SplitData.CHROMOSOME); + variantStorageEngine.index(Collections.singletonList(getResourceUri("by_chr/chr21.variant-test-file.vcf.gz")), outputUri); + } + + @Test + public void testMultiChromosomeSplitDataConcurrentFail3() throws Exception { + // Test goal: + // - Ensure file can be loaded after deleting a file with shared samples without any LOAD_SPLIT_DATA. + // Test steps: + // - Fail at loading chr20 (left the file in status "RUNNING") + // - Force remove chr20 + // - Index chr21 correctly + + variantStorageEngine.getOptions().put(VariantStorageOptions.STUDY.key(), STUDY_NAME); + failAtLoadingFile("by_chr/", "chr20.variant-test-file.vcf.gz", outputUri); + + variantStorageEngine.getOptions().put(VariantStorageOptions.FORCE.key(), true); + variantStorageEngine.removeFile(STUDY_NAME, "chr20.variant-test-file.vcf.gz", outputUri); + variantStorageEngine.getOptions().put(VariantStorageOptions.FORCE.key(), false); + + variantStorageEngine.index(Collections.singletonList(getResourceUri("by_chr/chr21.variant-test-file.vcf.gz")), outputUri); + } + + @Test + public void testMultiChromosomeSplitDataConcurrentFailDelete() throws Exception { + variantStorageEngine.getOptions().put(VariantStorageOptions.STUDY.key(), STUDY_NAME); + failAtLoadingFile("by_chr/", "chr20.variant-test-file.vcf.gz", outputUri); + + variantStorageEngine.getOptions().put(VariantStorageOptions.LOAD_SPLIT_DATA.key(), VariantStorageEngine.SplitData.CHROMOSOME); + variantStorageEngine.index(Collections.singletonList(getResourceUri("by_chr/chr21.variant-test-file.vcf.gz")), outputUri); + + try { + // FORCE=true is needed, as the file is not correctly indexed + // Set FORCE=false to assert exception + variantStorageEngine.getOptions().put(VariantStorageOptions.FORCE.key(), false); + variantStorageEngine.removeFile(STUDY_NAME, "chr20.variant-test-file.vcf.gz", outputUri); + fail(); + } catch (StorageEngineException e) { + assertEquals("Unable to remove non indexed file: chr20.variant-test-file.vcf.gz", e.getMessage()); + } + + // FORCE=true is needed, as the file is not correctly indexed + failAtDeletingFile("chr20.variant-test-file.vcf.gz", outputUri, 1, new ObjectMap(VariantStorageOptions.FORCE.key(), true)); + + try { + // FORCE=true is needed, as the file is not correctly indexed + variantStorageEngine.getOptions().put(VariantStorageOptions.FORCE.key(), true); + // RESUME=true is needed, as the delete task is in status "RUNNING" from the previous failAtDeletingFile + // Set RESUME=false to assert exception + variantStorageEngine.getOptions().put(VariantStorageOptions.RESUME.key(), false); + variantStorageEngine.removeFile(STUDY_NAME, "chr20.variant-test-file.vcf.gz", outputUri); + fail(); + } catch (StorageEngineException e) { + assertEquals("Operation \"remove\" for files [\"chr20.variant-test-file.vcf.gz\" (id=1)] in status \"RUNNING\". Relaunch with resume=true to finish the operation.", e.getMessage()); + } + + + // FORCE=true is needed, as the file is not correctly indexed + variantStorageEngine.getOptions().put(VariantStorageOptions.FORCE.key(), true); + // RESUME=true is needed, as the delete task is in status "RUNNING" + variantStorageEngine.getOptions().put(VariantStorageOptions.RESUME.key(), true); + variantStorageEngine.removeFile(STUDY_NAME, "chr20.variant-test-file.vcf.gz", outputUri); + } + @Test public void testMultiChromosomeSplitData() throws Exception { variantStorageEngine.getOptions().put(VariantStorageOptions.STUDY.key(), STUDY_NAME); @@ -131,6 +221,57 @@ public void testMultiChromosomeSplitData() throws Exception { }, QueryOptions.empty()); } + private void failAtLoadingFile(String x, String file1, URI outputUri) throws Exception { + try { + VariantStorageEngine engine = getMockedStorageEngine(new ObjectMap(VariantStorageOptions.STUDY.key(), STUDY_NAME)); + engine.index(Collections.singletonList(getResourceUri(x + file1)), outputUri); + fail("Should have thrown an exception"); + } catch (StoragePipelineException e) { + try { + assertEquals(MOCKED_EXCEPTION, e.getCause().getMessage()); + int studyId = metadataManager.getStudyId(STUDY_NAME); + FileMetadata fileMetadata = metadataManager.getFileMetadata(studyId, file1); + assertEquals(TaskMetadata.Status.NONE, fileMetadata.getIndexStatus()); + List runningTasks = new ArrayList<>(); + metadataManager.getRunningTasks(studyId).forEach(runningTasks::add); + assertEquals(1, runningTasks.size()); + assertEquals(TaskMetadata.Type.LOAD, runningTasks.get(0).getType()); + assertEquals(TaskMetadata.Status.RUNNING, runningTasks.get(0).currentStatus()); + assertEquals(Arrays.asList(fileMetadata.getId()), runningTasks.get(0).getFileIds()); + } catch (AssertionError error) { + e.printStackTrace(); + throw error; + } + } + } + + private void failAtDeletingFile(String file, URI outputUri, int expectedRunningTasks, ObjectMap options) throws Exception { + int studyId = metadataManager.getStudyId(STUDY_NAME); + FileMetadata fileMetadata = metadataManager.getFileMetadata(studyId, file); + try { + getMockedStorageEngine(options).removeFile(STUDY_NAME, file, outputUri); + fail("Should have thrown an exception"); + } catch (StorageEngineException e) { + try { + assertEquals(MOCKED_EXCEPTION, e.getMessage()); + assertEquals(TaskMetadata.Status.NONE, fileMetadata.getIndexStatus()); + List runningTasks = new ArrayList<>(); + metadataManager.getRunningTasks(studyId).forEach(runningTasks::add); + assertEquals(expectedRunningTasks, runningTasks.size()); + Optional optional = runningTasks.stream() + .filter(t -> t.getType() == TaskMetadata.Type.REMOVE && Arrays.asList(fileMetadata.getId()).equals(t.getFileIds())) + .findFirst(); + assertTrue(optional.isPresent()); + assertEquals(TaskMetadata.Type.REMOVE, optional.get().getType()); + assertEquals(TaskMetadata.Status.RUNNING, optional.get().currentStatus()); + assertEquals(Arrays.asList(fileMetadata.getId()), optional.get().getFileIds()); + } catch (AssertionError error) { + e.printStackTrace(); + throw error; + } + } + } + @Test public void testMultiChromosomeSplitDataVirtualFile() throws Exception { variantStorageEngine.getOptions().put(VariantStorageOptions.STUDY.key(), STUDY_NAME); @@ -406,6 +547,148 @@ private void checkIssueEntries_22_44681612_A_G(Variant v) { } + @Test + public void testLoadMultiFileDataConcurrency() throws Exception { + + URI outDir = newOutputUri(); + variantStorageEngine.getOptions().put(VariantStorageOptions.LOAD_MULTI_FILE_DATA.key(), false); + variantStorageEngine.getOptions().put(VariantStorageOptions.FAMILY.key(), true); + variantStorageEngine.getOptions().put(VariantStorageOptions.STUDY.key(), STUDY_NAME); + + String resourceDir = "by_chr/"; + String file1 = "chr22.variant-test-file.vcf.gz"; + String file2 = "chr22_1-2-DUP.variant-test-file.vcf.gz"; + + failAtLoadingFile(resourceDir, file1, outDir); + + try { + variantStorageEngine.index(Collections.singletonList(getResourceUri(resourceDir + file2)), outDir); + } catch (StoragePipelineException e) { + MatcherAssert.assertThat(e.getCause().getMessage(), startsWith("Can not \"Load\" files")); + MatcherAssert.assertThat(e.getCause().getMessage(), CoreMatchers.containsString(file2)); + MatcherAssert.assertThat(e.getCause().getMessage(), CoreMatchers.containsString(file1)); + } + + variantStorageEngine.getOptions().put(VariantStorageOptions.FORCE.key(), true); + variantStorageEngine.removeFile(STUDY_NAME, file1, outDir); + variantStorageEngine.index(Collections.singletonList(getResourceUri(resourceDir + file2)), outDir); + + variantStorageEngine.getOptions().put(VariantStorageOptions.LOAD_MULTI_FILE_DATA.key(), true); +// variantStorageEngine.getOptions().put(VariantStorageOptions.RESUME.key(), true); + variantStorageEngine.index(Collections.singletonList(getResourceUri(resourceDir + file1)), outDir); + } + + + @Test + public void testLoadMultiFileDataConcurrencyDeleteMany() throws Exception { + + URI outDir = newOutputUri(); + variantStorageEngine.getOptions().put(VariantStorageOptions.LOAD_MULTI_FILE_DATA.key(), false); + variantStorageEngine.getOptions().put(VariantStorageOptions.FAMILY.key(), true); + variantStorageEngine.getOptions().put(VariantStorageOptions.STUDY.key(), STUDY_NAME); + + String resourceDir = "platinum/"; + String file1 = "1K.end.platinum-genomes-vcf-NA12877_S1.vcf.gz"; + String file2 = "1K.end.platinum-genomes-vcf-NA12878_S1.vcf.gz"; + + failAtLoadingFile(resourceDir, file1, outDir); + failAtLoadingFile(resourceDir, file2, outDir); +// try { +// getMockedStorageEngine().index(Collections.singletonList(getResourceUri(resourceDir + file1)), outDir); +// fail("Should have thrown an exception"); +// } catch (StoragePipelineException e) { +// assertEquals(MOCKED_EXCEPTION, e.getCause().getMessage()); +// } +// try { +// getMockedStorageEngine().index(Collections.singletonList(getResourceUri(resourceDir + file2)), outDir); +// fail("Should have thrown an exception"); +// } catch (StoragePipelineException e) { +// assertEquals(MOCKED_EXCEPTION, e.getCause().getMessage()); +// } + + + variantStorageEngine.getOptions().put(VariantStorageOptions.FORCE.key(), true); + try { + variantStorageEngine.removeFile(STUDY_NAME, file1, outDir); + fail(); + } catch (StorageEngineException e) { + MatcherAssert.assertThat(e.getMessage(), startsWith("Can not \"remove\" files")); + MatcherAssert.assertThat(e.getMessage(), CoreMatchers.containsString(file1)); + MatcherAssert.assertThat(e.getMessage(), CoreMatchers.containsString(file2)); + } + try { + variantStorageEngine.removeFile(STUDY_NAME, file2, outDir); + fail(); + } catch (StorageEngineException e) { + MatcherAssert.assertThat(e.getMessage(), startsWith("Can not \"remove\" files")); + MatcherAssert.assertThat(e.getMessage(), CoreMatchers.containsString(file1)); + MatcherAssert.assertThat(e.getMessage(), CoreMatchers.containsString(file2)); + } + variantStorageEngine.removeFiles(STUDY_NAME, Arrays.asList(file1, file2), outDir); + + variantStorageEngine.index(Collections.singletonList(getResourceUri(resourceDir + file2)), outDir); + variantStorageEngine.index(Collections.singletonList(getResourceUri(resourceDir + file1)), outDir); + } + + @Test + public void testLoadMultiFileDataConcurrencyFail() throws Exception { + + URI outDir = newOutputUri(); + variantStorageEngine.getOptions().put(VariantStorageOptions.LOAD_MULTI_FILE_DATA.key(), false); + variantStorageEngine.getOptions().put(VariantStorageOptions.FAMILY.key(), true); + variantStorageEngine.getOptions().put(VariantStorageOptions.STUDY.key(), STUDY_NAME); + + String resourceDir = "by_chr/"; + String file1 = "chr22.variant-test-file.vcf.gz"; + String file2 = "chr22_1-2-DUP.variant-test-file.vcf.gz"; + + failAtLoadingFile(resourceDir, file1, outDir); + + try { + variantStorageEngine.index(Collections.singletonList(getResourceUri(resourceDir + file2)), outDir); + } catch (StoragePipelineException e) { + MatcherAssert.assertThat(e.getCause().getMessage(), startsWith("Can not \"Load\" files")); + MatcherAssert.assertThat(e.getCause().getMessage(), CoreMatchers.containsString(file2)); + MatcherAssert.assertThat(e.getCause().getMessage(), CoreMatchers.containsString(file1)); + } + + variantStorageEngine.getOptions().put(VariantStorageOptions.LOAD_MULTI_FILE_DATA.key(), true); + variantStorageEngine.getOptions().put(VariantStorageOptions.RESUME.key(), true); + variantStorageEngine.index(Collections.singletonList(getResourceUri(file1)), outDir); + + } + + private VariantStorageEngine getMockedStorageEngine() throws Exception { + return getMockedStorageEngine(new ObjectMap()); + } + + private VariantStorageEngine getMockedStorageEngine(ObjectMap options) throws Exception { + HadoopVariantStorageEngine mockedStorageEngine = Mockito.spy(getVariantStorageEngine()); + mockedStorageEngine.getOptions().putAll(options); + mockedStorageEngine.getOptions().put(VariantStorageOptions.STUDY.key(), STUDY_NAME); + VariantStoragePipeline mockedPipeline = Mockito.spy(variantStorageEngine.newStoragePipeline(true)); + + Mockito.doReturn(mockedPipeline).when(mockedStorageEngine).newStoragePipeline(Mockito.anyBoolean()); +// Mockito.doThrow(new StoragePipelineException(MOCKED_EXCEPTION, Collections.emptyList())).when(mockedPipeline).load(Mockito.any(), Mockito.any()); + Mockito.doAnswer(invocation -> { + // Throw StorageEngineException when calling load + System.out.printf("MOCKED load(%s, %s)%n", invocation.getArgument(0), invocation.getArgument(1)); + System.out.println("MOCKED load throw StorageEngineException"); + throw new StoragePipelineException(MOCKED_EXCEPTION, Collections.emptyList()); + }).when(mockedPipeline).load(Mockito.any(), Mockito.any()); + + Mockito.doAnswer(invocation -> { + // Call real method when calling preRemove, then throw StorageEngineException + System.out.printf("MOCKED preRemove(%s, %s, %s)%n", invocation.getArgument(0), invocation.getArgument(1), invocation.getArgument(2)); + System.out.println("MOCKED preRemove callRealMethod"); + invocation.callRealMethod(); + System.out.println("MOCKED preRemove callRealMethod DONE"); + System.out.println("MOCKED preRemove throw StorageEngineException"); + throw new StorageEngineException(MOCKED_EXCEPTION); + }).when(mockedStorageEngine).preRemove(Mockito.any(), Mockito.any(), Mockito.any()); + return mockedStorageEngine; + } + @Test public void testLoadByRegion() throws Exception { URI outDir = newOutputUri(); diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/test/java/org/opencb/opencga/storage/hadoop/variant/VariantHbaseTestUtils.java b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/test/java/org/opencb/opencga/storage/hadoop/variant/VariantHbaseTestUtils.java index 3557c5e55ff..e55f4bf5ea1 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/test/java/org/opencb/opencga/storage/hadoop/variant/VariantHbaseTestUtils.java +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/test/java/org/opencb/opencga/storage/hadoop/variant/VariantHbaseTestUtils.java @@ -46,6 +46,7 @@ import org.opencb.opencga.storage.core.metadata.models.StudyMetadata; import org.opencb.opencga.storage.core.variant.VariantStorageBaseTest; import org.opencb.opencga.storage.core.variant.VariantStorageOptions; +import org.opencb.opencga.storage.core.variant.adaptors.VariantQuery; import org.opencb.opencga.storage.core.variant.adaptors.VariantQueryParam; import org.opencb.opencga.storage.core.variant.adaptors.iterators.VariantDBIterator; import org.opencb.opencga.storage.core.variant.io.VariantWriterFactory; @@ -72,7 +73,6 @@ import java.util.zip.DataFormatException; import static org.opencb.opencga.storage.core.variant.VariantStorageBaseTest.getTmpRootDir; -import static org.opencb.opencga.storage.hadoop.variant.HadoopVariantStorageTest.configuration; /** * Utility class for VariantStorage hadoop tests @@ -236,8 +236,11 @@ private static void printVariantsFromDBAdaptor(VariantHadoopDBAdaptor dbAdaptor, } private static void printVariantsFromDBAdaptor(VariantHadoopDBAdaptor dbAdaptor, PrintStream out) { - VariantDBIterator iterator = dbAdaptor.iterator(new Query(VariantQueryParam.INCLUDE_SAMPLE_DATA.key(), "all,SAMPLE_ID") - .append(VariantQueryParam.INCLUDE_SAMPLE.key(), ParamConstants.ALL), + if (dbAdaptor.getMetadataManager().getStudyIds().isEmpty()) { + out.println("No studies found!"); + return; + } + VariantDBIterator iterator = dbAdaptor.iterator(new VariantQuery().includeSampleId(true).includeSampleAll(), new QueryOptions("simpleGenotypes", true)); ObjectMapper mapper = new ObjectMapper().configure(MapperFeature.REQUIRE_SETTERS_FOR_GETTERS, true); while (iterator.hasNext()) { From 06ba227e152bf43e5921685d60af9703b0d586ed Mon Sep 17 00:00:00 2001 From: JuanfeSanahuja Date: Mon, 29 Apr 2024 12:14:11 +0200 Subject: [PATCH 38/85] server: MailUtils enable SSL #TASK-464 --- .../main/java/org/opencb/opencga/core/common/MailUtils.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/opencga-core/src/main/java/org/opencb/opencga/core/common/MailUtils.java b/opencga-core/src/main/java/org/opencb/opencga/core/common/MailUtils.java index 7181db48b89..45c6d58ca06 100644 --- a/opencga-core/src/main/java/org/opencb/opencga/core/common/MailUtils.java +++ b/opencga-core/src/main/java/org/opencb/opencga/core/common/MailUtils.java @@ -39,7 +39,8 @@ public static void sendResetPasswordMail(String to, String newPassword, final St Properties props = new Properties(); props.put("mail.smtp.auth", "true"); - props.put("mail.smtp.starttls.enable", ssl); + // props.put("mail.smtp.starttls.enable", ssl); + props.put("mail.smtp.ssl.enable", ssl); props.put("mail.smtp.host", mailHost); props.put("mail.smtp.port", mailPort); From 4338023e54bb95dd8853f3bc3f082680bcd5880c Mon Sep 17 00:00:00 2001 From: JuanfeSanahuja Date: Mon, 29 Apr 2024 13:26:53 +0200 Subject: [PATCH 39/85] server: added properties to mail MailUtils #TASK-464 --- .../main/java/org/opencb/opencga/core/common/MailUtils.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/opencga-core/src/main/java/org/opencb/opencga/core/common/MailUtils.java b/opencga-core/src/main/java/org/opencb/opencga/core/common/MailUtils.java index 45c6d58ca06..e09fd420207 100644 --- a/opencga-core/src/main/java/org/opencb/opencga/core/common/MailUtils.java +++ b/opencga-core/src/main/java/org/opencb/opencga/core/common/MailUtils.java @@ -39,11 +39,13 @@ public static void sendResetPasswordMail(String to, String newPassword, final St Properties props = new Properties(); props.put("mail.smtp.auth", "true"); - // props.put("mail.smtp.starttls.enable", ssl); props.put("mail.smtp.ssl.enable", ssl); props.put("mail.smtp.host", mailHost); props.put("mail.smtp.port", mailPort); - + props.put("mail.smtp.starttls.enable", "true"); + props.put("mail.smtp.starttls.required", "true"); + props.put("mail.smtp.ssl.protocols", "TLSv1.2"); + props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory"); Session session = Session.getInstance(props, new javax.mail.Authenticator() { protected PasswordAuthentication getPasswordAuthentication() { From 15576c99a34d162ea426123ea923317baf96d00c Mon Sep 17 00:00:00 2001 From: JuanfeSanahuja Date: Mon, 29 Apr 2024 14:25:25 +0200 Subject: [PATCH 40/85] server: Change userName for userId #TASK-464 --- .../auth/authentication/CatalogAuthenticationManager.java | 2 +- .../main/java/org/opencb/opencga/core/common/MailUtils.java | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/auth/authentication/CatalogAuthenticationManager.java b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/auth/authentication/CatalogAuthenticationManager.java index 2c14d8c78fa..d86d778a1e2 100644 --- a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/auth/authentication/CatalogAuthenticationManager.java +++ b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/auth/authentication/CatalogAuthenticationManager.java @@ -134,7 +134,7 @@ public OpenCGAResult resetPassword(String userId) throws CatalogException { String mailPort = this.emailConfig.getPort(); try { MailUtils.sendResetPasswordMail(email, newPassword, mailUser, mailPassword, mailHost, mailPort, - "true", ((User) user.getResults().get(0)).getName()); + "true", ((User) user.getResults().get(0)).getId()); result = userDBAdaptor.resetPassword(userId, email, newPassword); } catch (Exception e) { throw new CatalogException("Email could not be sent.", e); diff --git a/opencga-core/src/main/java/org/opencb/opencga/core/common/MailUtils.java b/opencga-core/src/main/java/org/opencb/opencga/core/common/MailUtils.java index e09fd420207..7ff75f86698 100644 --- a/opencga-core/src/main/java/org/opencb/opencga/core/common/MailUtils.java +++ b/opencga-core/src/main/java/org/opencb/opencga/core/common/MailUtils.java @@ -35,7 +35,7 @@ public class MailUtils { private static final Logger logger = LoggerFactory.getLogger(MailUtils.class); public static void sendResetPasswordMail(String to, String newPassword, final String mailUser, final String mailPassword, - String mailHost, String mailPort, String ssl, String UserName) throws Exception { + String mailHost, String mailPort, String ssl, String user_id) throws Exception { Properties props = new Properties(); props.put("mail.smtp.auth", "true"); @@ -59,7 +59,7 @@ protected PasswordAuthentication getPasswordAuthentication() { InternetAddress.parse(to)); message.setSubject("XetaBase: Password Reset"); - message.setText(getEmailContent(UserName,newPassword)); + message.setText(getEmailContent(user_id,newPassword)); Transport.send(message); } From accfa3b86d7edff6ef67a6a1c1588ed8fae079b6 Mon Sep 17 00:00:00 2001 From: pfurio Date: Tue, 30 Apr 2024 10:20:19 +0200 Subject: [PATCH 41/85] catalog: fix FORMAT and bioformat regex queries, #TASK-5932 --- .../db/mongodb/FileMongoDBAdaptor.java | 9 ++----- .../catalog/managers/FileManagerTest.java | 26 +++++++++++++++++++ 2 files changed, 28 insertions(+), 7 deletions(-) diff --git a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/FileMongoDBAdaptor.java b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/FileMongoDBAdaptor.java index a0811254e65..38d24ed6674 100644 --- a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/FileMongoDBAdaptor.java +++ b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/FileMongoDBAdaptor.java @@ -1479,13 +1479,6 @@ private Bson parseQuery(Query query, Document extraQuery, String user) addAutoOrQuery(queryParam.key(), queryParam.key(), myQuery, queryParam.type(), andBsonList); } break; - case FORMAT: - case BIOFORMAT: - // Replace the value for an uppercase string as we know it will always be in that way - String uppercaseValue = myQuery.getString(queryParam.key()).toUpperCase(); - myQuery.put(queryParam.key(), uppercaseValue); - addAutoOrQuery(queryParam.key(), queryParam.key(), myQuery, queryParam.type(), andBsonList); - break; case UUID: case EXTERNAL: case TYPE: @@ -1493,6 +1486,8 @@ private Bson parseQuery(Query query, Document extraQuery, String user) case ID: case PATH: case RELEASE: + case FORMAT: + case BIOFORMAT: case TAGS: case SIZE: case SOFTWARE_NAME: diff --git a/opencga-catalog/src/test/java/org/opencb/opencga/catalog/managers/FileManagerTest.java b/opencga-catalog/src/test/java/org/opencb/opencga/catalog/managers/FileManagerTest.java index a0517b1294a..c01d915498c 100644 --- a/opencga-catalog/src/test/java/org/opencb/opencga/catalog/managers/FileManagerTest.java +++ b/opencga-catalog/src/test/java/org/opencb/opencga/catalog/managers/FileManagerTest.java @@ -188,6 +188,32 @@ public void testLinkFileWithoutReadPermissions() throws IOException, CatalogExce fileManager.link(studyFqn, new FileLinkParams().setUri(file.getPath()), false, token); } + @Test + public void filterByFormatTest() throws CatalogException { + Query query = new Query(FileDBAdaptor.QueryParams.FORMAT.key(), "PLAIN"); + OpenCGAResult search = catalogManager.getFileManager().search(studyFqn, query, QueryOptions.empty(), token); + assertEquals(2, search.getNumResults()); + + query = new Query(FileDBAdaptor.QueryParams.FORMAT.key(), "plain"); + search = catalogManager.getFileManager().search(studyFqn, query, QueryOptions.empty(), token); + assertEquals(0, search.getNumResults()); + + // Case sensitive search in lower case + query = new Query(FileDBAdaptor.QueryParams.FORMAT.key(), "~/^pla/"); + search = catalogManager.getFileManager().search(studyFqn, query, QueryOptions.empty(), token); + assertEquals(0, search.getNumResults()); + + // Case sensitive in upper case + query = new Query(FileDBAdaptor.QueryParams.FORMAT.key(), "~/^PLA/"); + search = catalogManager.getFileManager().search(studyFqn, query, QueryOptions.empty(), token); + assertEquals(2, search.getNumResults()); + + // Case insensitive search + query = new Query(FileDBAdaptor.QueryParams.FORMAT.key(), "~/^pla/i"); + search = catalogManager.getFileManager().search(studyFqn, query, QueryOptions.empty(), token); + assertEquals(2, search.getNumResults()); + } + @Test public void createDirectoryTest() throws CatalogException { FileCreateParams params = new FileCreateParams() From 4a33662ac2d17fa6fe9ce1682e3590e8c7289254 Mon Sep 17 00:00:00 2001 From: JuanfeSanahuja Date: Tue, 30 Apr 2024 11:34:31 +0200 Subject: [PATCH 42/85] Prepare release 2.12.4 --- opencga-analysis/pom.xml | 2 +- opencga-app/pom.xml | 2 +- opencga-catalog/pom.xml | 2 +- opencga-client/pom.xml | 2 +- opencga-clinical/pom.xml | 2 +- opencga-core/pom.xml | 2 +- opencga-master/pom.xml | 2 +- opencga-server/pom.xml | 2 +- opencga-storage/opencga-storage-app/pom.xml | 2 +- opencga-storage/opencga-storage-benchmark/pom.xml | 2 +- opencga-storage/opencga-storage-core/pom.xml | 2 +- .../opencga-storage-hadoop-core/pom.xml | 2 +- .../opencga-storage-hadoop-deps-emr6.1/pom.xml | 2 +- .../opencga-storage-hadoop-deps-hdp2.6/pom.xml | 2 +- .../opencga-storage-hadoop-deps-hdp3.1/pom.xml | 2 +- .../opencga-storage-hadoop-deps/pom.xml | 2 +- opencga-storage/opencga-storage-hadoop/pom.xml | 2 +- opencga-storage/opencga-storage-server/pom.xml | 2 +- opencga-storage/pom.xml | 2 +- opencga-test/pom.xml | 2 +- pom.xml | 14 +++++++------- 21 files changed, 27 insertions(+), 27 deletions(-) diff --git a/opencga-analysis/pom.xml b/opencga-analysis/pom.xml index 4958a137880..b9dfad55dc4 100644 --- a/opencga-analysis/pom.xml +++ b/opencga-analysis/pom.xml @@ -22,7 +22,7 @@ org.opencb.opencga opencga - 2.12.4-SNAPSHOT + 2.12.4 ../pom.xml diff --git a/opencga-app/pom.xml b/opencga-app/pom.xml index 3daac8c0301..4a1ed3c2907 100644 --- a/opencga-app/pom.xml +++ b/opencga-app/pom.xml @@ -22,7 +22,7 @@ org.opencb.opencga opencga - 2.12.4-SNAPSHOT + 2.12.4 ../pom.xml diff --git a/opencga-catalog/pom.xml b/opencga-catalog/pom.xml index e20025edd44..7a0a54910ce 100644 --- a/opencga-catalog/pom.xml +++ b/opencga-catalog/pom.xml @@ -23,7 +23,7 @@ org.opencb.opencga opencga - 2.12.4-SNAPSHOT + 2.12.4 ../pom.xml diff --git a/opencga-client/pom.xml b/opencga-client/pom.xml index 35402c7c932..797cdbcaabd 100644 --- a/opencga-client/pom.xml +++ b/opencga-client/pom.xml @@ -22,7 +22,7 @@ org.opencb.opencga opencga - 2.12.4-SNAPSHOT + 2.12.4 ../pom.xml diff --git a/opencga-clinical/pom.xml b/opencga-clinical/pom.xml index 3ae7d4f552b..3deebdfe00c 100644 --- a/opencga-clinical/pom.xml +++ b/opencga-clinical/pom.xml @@ -5,7 +5,7 @@ org.opencb.opencga opencga - 2.12.4-SNAPSHOT + 2.12.4 ../pom.xml 4.0.0 diff --git a/opencga-core/pom.xml b/opencga-core/pom.xml index 7d949bb6f58..d1bce7dd255 100644 --- a/opencga-core/pom.xml +++ b/opencga-core/pom.xml @@ -22,7 +22,7 @@ org.opencb.opencga opencga - 2.12.4-SNAPSHOT + 2.12.4 ../pom.xml diff --git a/opencga-master/pom.xml b/opencga-master/pom.xml index 4df3d66a007..555b40fd93c 100644 --- a/opencga-master/pom.xml +++ b/opencga-master/pom.xml @@ -22,7 +22,7 @@ opencga org.opencb.opencga - 2.12.4-SNAPSHOT + 2.12.4 ../pom.xml diff --git a/opencga-server/pom.xml b/opencga-server/pom.xml index 326718f8022..00cd35d1974 100644 --- a/opencga-server/pom.xml +++ b/opencga-server/pom.xml @@ -22,7 +22,7 @@ org.opencb.opencga opencga - 2.12.4-SNAPSHOT + 2.12.4 ../pom.xml diff --git a/opencga-storage/opencga-storage-app/pom.xml b/opencga-storage/opencga-storage-app/pom.xml index 2823f273f28..b50473c3dea 100644 --- a/opencga-storage/opencga-storage-app/pom.xml +++ b/opencga-storage/opencga-storage-app/pom.xml @@ -22,7 +22,7 @@ org.opencb.opencga opencga-storage - 2.12.4-SNAPSHOT + 2.12.4 ../pom.xml diff --git a/opencga-storage/opencga-storage-benchmark/pom.xml b/opencga-storage/opencga-storage-benchmark/pom.xml index cc328a5fdd8..237df394693 100644 --- a/opencga-storage/opencga-storage-benchmark/pom.xml +++ b/opencga-storage/opencga-storage-benchmark/pom.xml @@ -22,7 +22,7 @@ opencga-storage org.opencb.opencga - 2.12.4-SNAPSHOT + 2.12.4 ../pom.xml diff --git a/opencga-storage/opencga-storage-core/pom.xml b/opencga-storage/opencga-storage-core/pom.xml index 00bf4226afd..a78bc108cd3 100644 --- a/opencga-storage/opencga-storage-core/pom.xml +++ b/opencga-storage/opencga-storage-core/pom.xml @@ -22,7 +22,7 @@ org.opencb.opencga opencga-storage - 2.12.4-SNAPSHOT + 2.12.4 ../pom.xml diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/pom.xml b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/pom.xml index 453935bf26c..ae1663ed408 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/pom.xml +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/pom.xml @@ -23,7 +23,7 @@ org.opencb.opencga opencga-storage-hadoop - 2.12.4-SNAPSHOT + 2.12.4 ../pom.xml diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-deps/opencga-storage-hadoop-deps-emr6.1/pom.xml b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-deps/opencga-storage-hadoop-deps-emr6.1/pom.xml index 9df46c71579..299f46d55e1 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-deps/opencga-storage-hadoop-deps-emr6.1/pom.xml +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-deps/opencga-storage-hadoop-deps-emr6.1/pom.xml @@ -22,7 +22,7 @@ org.opencb.opencga opencga-storage-hadoop-deps - 2.12.4-SNAPSHOT + 2.12.4 ../pom.xml diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-deps/opencga-storage-hadoop-deps-hdp2.6/pom.xml b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-deps/opencga-storage-hadoop-deps-hdp2.6/pom.xml index 64a1da9403f..d39f818fa65 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-deps/opencga-storage-hadoop-deps-hdp2.6/pom.xml +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-deps/opencga-storage-hadoop-deps-hdp2.6/pom.xml @@ -22,7 +22,7 @@ org.opencb.opencga opencga-storage-hadoop-deps - 2.12.4-SNAPSHOT + 2.12.4 ../pom.xml diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-deps/opencga-storage-hadoop-deps-hdp3.1/pom.xml b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-deps/opencga-storage-hadoop-deps-hdp3.1/pom.xml index b1eae85ecec..c80452c7b80 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-deps/opencga-storage-hadoop-deps-hdp3.1/pom.xml +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-deps/opencga-storage-hadoop-deps-hdp3.1/pom.xml @@ -22,7 +22,7 @@ org.opencb.opencga opencga-storage-hadoop-deps - 2.12.4-SNAPSHOT + 2.12.4 ../pom.xml diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-deps/pom.xml b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-deps/pom.xml index 164bbcc0560..fb5c1500b27 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-deps/pom.xml +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-deps/pom.xml @@ -50,7 +50,7 @@ org.opencb.opencga opencga-storage-hadoop - 2.12.4-SNAPSHOT + 2.12.4 ../pom.xml diff --git a/opencga-storage/opencga-storage-hadoop/pom.xml b/opencga-storage/opencga-storage-hadoop/pom.xml index 6e0196b0eb8..eb724763958 100644 --- a/opencga-storage/opencga-storage-hadoop/pom.xml +++ b/opencga-storage/opencga-storage-hadoop/pom.xml @@ -28,7 +28,7 @@ org.opencb.opencga opencga-storage - 2.12.4-SNAPSHOT + 2.12.4 ../pom.xml diff --git a/opencga-storage/opencga-storage-server/pom.xml b/opencga-storage/opencga-storage-server/pom.xml index 9ec6f2f1ab3..4927f1d5263 100644 --- a/opencga-storage/opencga-storage-server/pom.xml +++ b/opencga-storage/opencga-storage-server/pom.xml @@ -22,7 +22,7 @@ org.opencb.opencga opencga-storage - 2.12.4-SNAPSHOT + 2.12.4 ../pom.xml diff --git a/opencga-storage/pom.xml b/opencga-storage/pom.xml index 0c2ccaae662..5796b008eed 100644 --- a/opencga-storage/pom.xml +++ b/opencga-storage/pom.xml @@ -22,7 +22,7 @@ org.opencb.opencga opencga - 2.12.4-SNAPSHOT + 2.12.4 ../pom.xml diff --git a/opencga-test/pom.xml b/opencga-test/pom.xml index 469922d6d88..0840b6813d5 100644 --- a/opencga-test/pom.xml +++ b/opencga-test/pom.xml @@ -24,7 +24,7 @@ org.opencb.opencga opencga - 2.12.4-SNAPSHOT + 2.12.4 ../pom.xml diff --git a/pom.xml b/pom.xml index 6421b21012a..893c4f54869 100644 --- a/pom.xml +++ b/pom.xml @@ -22,7 +22,7 @@ org.opencb.opencga opencga - 2.12.4-SNAPSHOT + 2.12.4 pom OpenCGA @@ -43,12 +43,12 @@ - 2.12.4_dev - 2.12.4_dev - 5.8.3-SNAPSHOT - 2.12.2-SNAPSHOT - 4.12.1-SNAPSHOT - 2.12.4-SNAPSHOT + 2.12.4 + 2.12.4 + 5.8.3 + 2.12.2 + 4.12.0 + 2.12.4 0.2.0 2.11.4 From ae255c3650e49b6ddcf5abe6e358372e9955c3d3 Mon Sep 17 00:00:00 2001 From: JuanfeSanahuja Date: Tue, 30 Apr 2024 11:37:16 +0200 Subject: [PATCH 43/85] Prepare next release 2.12.5-SNAPSHOT --- opencga-analysis/pom.xml | 2 +- opencga-app/pom.xml | 2 +- opencga-catalog/pom.xml | 2 +- opencga-client/pom.xml | 2 +- opencga-clinical/pom.xml | 2 +- opencga-core/pom.xml | 2 +- opencga-master/pom.xml | 2 +- opencga-server/pom.xml | 2 +- opencga-storage/opencga-storage-app/pom.xml | 2 +- opencga-storage/opencga-storage-benchmark/pom.xml | 2 +- opencga-storage/opencga-storage-core/pom.xml | 2 +- .../opencga-storage-hadoop-core/pom.xml | 2 +- .../opencga-storage-hadoop-deps-emr6.1/pom.xml | 2 +- .../opencga-storage-hadoop-deps-hdp2.6/pom.xml | 2 +- .../opencga-storage-hadoop-deps-hdp3.1/pom.xml | 2 +- .../opencga-storage-hadoop-deps/pom.xml | 2 +- opencga-storage/opencga-storage-hadoop/pom.xml | 2 +- opencga-storage/opencga-storage-server/pom.xml | 2 +- opencga-storage/pom.xml | 2 +- opencga-test/pom.xml | 2 +- pom.xml | 14 +++++++------- 21 files changed, 27 insertions(+), 27 deletions(-) diff --git a/opencga-analysis/pom.xml b/opencga-analysis/pom.xml index b9dfad55dc4..0e8c8b94814 100644 --- a/opencga-analysis/pom.xml +++ b/opencga-analysis/pom.xml @@ -22,7 +22,7 @@ org.opencb.opencga opencga - 2.12.4 + 2.12.5-SNAPSHOT ../pom.xml diff --git a/opencga-app/pom.xml b/opencga-app/pom.xml index 4a1ed3c2907..ae72959c680 100644 --- a/opencga-app/pom.xml +++ b/opencga-app/pom.xml @@ -22,7 +22,7 @@ org.opencb.opencga opencga - 2.12.4 + 2.12.5-SNAPSHOT ../pom.xml diff --git a/opencga-catalog/pom.xml b/opencga-catalog/pom.xml index 7a0a54910ce..120850f20f8 100644 --- a/opencga-catalog/pom.xml +++ b/opencga-catalog/pom.xml @@ -23,7 +23,7 @@ org.opencb.opencga opencga - 2.12.4 + 2.12.5-SNAPSHOT ../pom.xml diff --git a/opencga-client/pom.xml b/opencga-client/pom.xml index 797cdbcaabd..dfe20bc1c6d 100644 --- a/opencga-client/pom.xml +++ b/opencga-client/pom.xml @@ -22,7 +22,7 @@ org.opencb.opencga opencga - 2.12.4 + 2.12.5-SNAPSHOT ../pom.xml diff --git a/opencga-clinical/pom.xml b/opencga-clinical/pom.xml index 3deebdfe00c..e17ae02a3c5 100644 --- a/opencga-clinical/pom.xml +++ b/opencga-clinical/pom.xml @@ -5,7 +5,7 @@ org.opencb.opencga opencga - 2.12.4 + 2.12.5-SNAPSHOT ../pom.xml 4.0.0 diff --git a/opencga-core/pom.xml b/opencga-core/pom.xml index d1bce7dd255..f64f0c82cd5 100644 --- a/opencga-core/pom.xml +++ b/opencga-core/pom.xml @@ -22,7 +22,7 @@ org.opencb.opencga opencga - 2.12.4 + 2.12.5-SNAPSHOT ../pom.xml diff --git a/opencga-master/pom.xml b/opencga-master/pom.xml index 555b40fd93c..3010de9e741 100644 --- a/opencga-master/pom.xml +++ b/opencga-master/pom.xml @@ -22,7 +22,7 @@ opencga org.opencb.opencga - 2.12.4 + 2.12.5-SNAPSHOT ../pom.xml diff --git a/opencga-server/pom.xml b/opencga-server/pom.xml index 00cd35d1974..35730710dd5 100644 --- a/opencga-server/pom.xml +++ b/opencga-server/pom.xml @@ -22,7 +22,7 @@ org.opencb.opencga opencga - 2.12.4 + 2.12.5-SNAPSHOT ../pom.xml diff --git a/opencga-storage/opencga-storage-app/pom.xml b/opencga-storage/opencga-storage-app/pom.xml index b50473c3dea..dee5f5ab22d 100644 --- a/opencga-storage/opencga-storage-app/pom.xml +++ b/opencga-storage/opencga-storage-app/pom.xml @@ -22,7 +22,7 @@ org.opencb.opencga opencga-storage - 2.12.4 + 2.12.5-SNAPSHOT ../pom.xml diff --git a/opencga-storage/opencga-storage-benchmark/pom.xml b/opencga-storage/opencga-storage-benchmark/pom.xml index 237df394693..f566fb8d61a 100644 --- a/opencga-storage/opencga-storage-benchmark/pom.xml +++ b/opencga-storage/opencga-storage-benchmark/pom.xml @@ -22,7 +22,7 @@ opencga-storage org.opencb.opencga - 2.12.4 + 2.12.5-SNAPSHOT ../pom.xml diff --git a/opencga-storage/opencga-storage-core/pom.xml b/opencga-storage/opencga-storage-core/pom.xml index a78bc108cd3..d2569f51505 100644 --- a/opencga-storage/opencga-storage-core/pom.xml +++ b/opencga-storage/opencga-storage-core/pom.xml @@ -22,7 +22,7 @@ org.opencb.opencga opencga-storage - 2.12.4 + 2.12.5-SNAPSHOT ../pom.xml diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/pom.xml b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/pom.xml index ae1663ed408..98684f89345 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/pom.xml +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/pom.xml @@ -23,7 +23,7 @@ org.opencb.opencga opencga-storage-hadoop - 2.12.4 + 2.12.5-SNAPSHOT ../pom.xml diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-deps/opencga-storage-hadoop-deps-emr6.1/pom.xml b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-deps/opencga-storage-hadoop-deps-emr6.1/pom.xml index 299f46d55e1..c40bd0c545e 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-deps/opencga-storage-hadoop-deps-emr6.1/pom.xml +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-deps/opencga-storage-hadoop-deps-emr6.1/pom.xml @@ -22,7 +22,7 @@ org.opencb.opencga opencga-storage-hadoop-deps - 2.12.4 + 2.12.5-SNAPSHOT ../pom.xml diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-deps/opencga-storage-hadoop-deps-hdp2.6/pom.xml b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-deps/opencga-storage-hadoop-deps-hdp2.6/pom.xml index d39f818fa65..f2ab268c070 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-deps/opencga-storage-hadoop-deps-hdp2.6/pom.xml +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-deps/opencga-storage-hadoop-deps-hdp2.6/pom.xml @@ -22,7 +22,7 @@ org.opencb.opencga opencga-storage-hadoop-deps - 2.12.4 + 2.12.5-SNAPSHOT ../pom.xml diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-deps/opencga-storage-hadoop-deps-hdp3.1/pom.xml b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-deps/opencga-storage-hadoop-deps-hdp3.1/pom.xml index c80452c7b80..c78627c4980 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-deps/opencga-storage-hadoop-deps-hdp3.1/pom.xml +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-deps/opencga-storage-hadoop-deps-hdp3.1/pom.xml @@ -22,7 +22,7 @@ org.opencb.opencga opencga-storage-hadoop-deps - 2.12.4 + 2.12.5-SNAPSHOT ../pom.xml diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-deps/pom.xml b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-deps/pom.xml index fb5c1500b27..5f0d66e4a26 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-deps/pom.xml +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-deps/pom.xml @@ -50,7 +50,7 @@ org.opencb.opencga opencga-storage-hadoop - 2.12.4 + 2.12.5-SNAPSHOT ../pom.xml diff --git a/opencga-storage/opencga-storage-hadoop/pom.xml b/opencga-storage/opencga-storage-hadoop/pom.xml index eb724763958..ede0e9d5479 100644 --- a/opencga-storage/opencga-storage-hadoop/pom.xml +++ b/opencga-storage/opencga-storage-hadoop/pom.xml @@ -28,7 +28,7 @@ org.opencb.opencga opencga-storage - 2.12.4 + 2.12.5-SNAPSHOT ../pom.xml diff --git a/opencga-storage/opencga-storage-server/pom.xml b/opencga-storage/opencga-storage-server/pom.xml index 4927f1d5263..46032914536 100644 --- a/opencga-storage/opencga-storage-server/pom.xml +++ b/opencga-storage/opencga-storage-server/pom.xml @@ -22,7 +22,7 @@ org.opencb.opencga opencga-storage - 2.12.4 + 2.12.5-SNAPSHOT ../pom.xml diff --git a/opencga-storage/pom.xml b/opencga-storage/pom.xml index 5796b008eed..b318a6c26bb 100644 --- a/opencga-storage/pom.xml +++ b/opencga-storage/pom.xml @@ -22,7 +22,7 @@ org.opencb.opencga opencga - 2.12.4 + 2.12.5-SNAPSHOT ../pom.xml diff --git a/opencga-test/pom.xml b/opencga-test/pom.xml index 0840b6813d5..ae075a55888 100644 --- a/opencga-test/pom.xml +++ b/opencga-test/pom.xml @@ -24,7 +24,7 @@ org.opencb.opencga opencga - 2.12.4 + 2.12.5-SNAPSHOT ../pom.xml diff --git a/pom.xml b/pom.xml index 893c4f54869..29536c3be50 100644 --- a/pom.xml +++ b/pom.xml @@ -22,7 +22,7 @@ org.opencb.opencga opencga - 2.12.4 + 2.12.5-SNAPSHOT pom OpenCGA @@ -43,12 +43,12 @@ - 2.12.4 - 2.12.4 - 5.8.3 - 2.12.2 - 4.12.0 - 2.12.4 + 2.12.5_dev + 2.12.5_dev + 5.8.4-SNAPSHOT + 2.12.3-SNAPSHOT + 4.12.1-SNAPSHOT + 2.12.5-SNAPSHOT 0.2.0 2.11.4 From f4f67c2afdefa86fae72773accecc54bed7c39a7 Mon Sep 17 00:00:00 2001 From: pfurio Date: Thu, 2 May 2024 13:00:10 +0200 Subject: [PATCH 44/85] catalog: remove references from cases when file is deleted, #TASK-5535 --- .../ClinicalAnalysisMongoDBAdaptor.java | 27 ++++++- .../db/mongodb/FileMongoDBAdaptor.java | 1 + .../opencga/catalog/managers/FileManager.java | 17 +++-- .../catalog/managers/FileManagerTest.java | 73 +++++++++++++++++++ 4 files changed, 110 insertions(+), 8 deletions(-) diff --git a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/ClinicalAnalysisMongoDBAdaptor.java b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/ClinicalAnalysisMongoDBAdaptor.java index dd5b90a22d8..078554b4737 100644 --- a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/ClinicalAnalysisMongoDBAdaptor.java +++ b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/ClinicalAnalysisMongoDBAdaptor.java @@ -31,9 +31,7 @@ import org.opencb.commons.datastore.core.*; import org.opencb.commons.datastore.mongodb.MongoDBCollection; import org.opencb.commons.datastore.mongodb.MongoDBIterator; -import org.opencb.opencga.catalog.db.api.ClinicalAnalysisDBAdaptor; -import org.opencb.opencga.catalog.db.api.DBIterator; -import org.opencb.opencga.catalog.db.api.InterpretationDBAdaptor; +import org.opencb.opencga.catalog.db.api.*; import org.opencb.opencga.catalog.db.mongodb.converters.ClinicalAnalysisConverter; import org.opencb.opencga.catalog.db.mongodb.iterators.ClinicalAnalysisCatalogMongoDBIterator; import org.opencb.opencga.catalog.exceptions.CatalogAuthorizationException; @@ -151,6 +149,10 @@ static void fixFilesForRemoval(ObjectMap parameters, String key) { for (Object file : parameters.getAsList(key)) { if (file instanceof File) { fileParamList.add(new Document("uid", ((File) file).getUid())); + } else if (file instanceof Document) { + fileParamList.add(new Document("uid", ((Document) file).get("uid"))); + } else { + throw new IllegalArgumentException("Expected a File or Document object"); } } parameters.put(key, fileParamList); @@ -814,6 +816,25 @@ OpenCGAResult privateDelete(ClientSession clientSession, ClinicalAnalysis cli return endWrite(tmpStartTime, 1, 0, 0, 1, Collections.emptyList()); } + void removeFileReferences(ClientSession clientSession, long studyUid, long fileUid, Document file) + throws CatalogParameterException, CatalogDBException, CatalogAuthorizationException { + ObjectMap parameters = new ObjectMap(FILES.key(), Collections.singletonList(file)); + ObjectMap actionMap = new ObjectMap(FILES.key(), ParamUtils.BasicUpdateAction.REMOVE); + QueryOptions options = new QueryOptions(Constants.ACTIONS, actionMap); + + Query query = new Query() + .append(QueryParams.STUDY_UID.key(), studyUid) + .append(QueryParams.FILES_UID.key(), fileUid); + OpenCGAResult result = get(query, ClinicalAnalysisManager.INCLUDE_CLINICAL_IDS); + for (ClinicalAnalysis clinicalAnalysis : result.getResults()) { + logger.debug("Removing file references from Clinical Analysis {}", clinicalAnalysis.getId()); + ClinicalAudit clinicalAudit = new ClinicalAudit("OPENCGA", ClinicalAudit.Action.UPDATE_CLINICAL_ANALYSIS, "File " + + file.getString(FileDBAdaptor.QueryParams.PATH.key()) + " was deleted. Remove file references from case.", + TimeUtils.getTime()); + transactionalUpdate(clientSession, clinicalAnalysis, parameters, null, Collections.singletonList(clinicalAudit), options); + } + } + @Override public OpenCGAResult restore(long id, QueryOptions queryOptions) throws CatalogDBException { return null; diff --git a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/FileMongoDBAdaptor.java b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/FileMongoDBAdaptor.java index a0811254e65..3b5a14684b4 100644 --- a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/FileMongoDBAdaptor.java +++ b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/FileMongoDBAdaptor.java @@ -1008,6 +1008,7 @@ OpenCGAResult privateDelete(ClientSession clientSession, Document fileDo long tmpFileUid = tmpFile.getLong(PRIVATE_UID); dbAdaptorFactory.getCatalogJobDBAdaptor().removeFileReferences(clientSession, studyUid, tmpFileUid, tmpFile); + dbAdaptorFactory.getClinicalAnalysisDBAdaptor().removeFileReferences(clientSession, studyUid, tmpFileUid, tmpFile); // Set status nestedPut(QueryParams.INTERNAL_STATUS.key(), getMongoDBDocument(new FileStatus(status), "status"), tmpFile); diff --git a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/managers/FileManager.java b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/managers/FileManager.java index 0832d689440..f1bd98c2a90 100644 --- a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/managers/FileManager.java +++ b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/managers/FileManager.java @@ -30,10 +30,7 @@ import org.opencb.commons.utils.ListUtils; import org.opencb.opencga.catalog.auth.authorization.AuthorizationManager; import org.opencb.opencga.catalog.db.DBAdaptorFactory; -import org.opencb.opencga.catalog.db.api.DBIterator; -import org.opencb.opencga.catalog.db.api.FileDBAdaptor; -import org.opencb.opencga.catalog.db.api.SampleDBAdaptor; -import org.opencb.opencga.catalog.db.api.StudyDBAdaptor; +import org.opencb.opencga.catalog.db.api.*; import org.opencb.opencga.catalog.db.mongodb.MongoDBAdaptorFactory; import org.opencb.opencga.catalog.exceptions.*; import org.opencb.opencga.catalog.io.IOManager; @@ -1836,7 +1833,7 @@ public OpenCGAResult unlink(@Nullable String studyId, String fileId, Strin } catch (CatalogException e) { auditManager.audit(userId, Enums.Action.UNLINK, Enums.Resource.FILE, fileId, "", study.getId(), study.getUuid(), auditParams, new AuditRecord.Status(AuditRecord.Status.Result.ERROR, e.getError())); - throw e; + throw new CatalogException("Could not unlink file '" + fileId + "'", e); } } @@ -3100,6 +3097,16 @@ private void checkCanDeleteFile(Study study, String fileId, boolean unlink, List // TODO: Validate no file/folder within any registered directory is not registered in OpenCGA } + Query clinicalQuery = new Query() + .append(ClinicalAnalysisDBAdaptor.QueryParams.STUDY_UID.key(), study.getUid()) + .append(ClinicalAnalysisDBAdaptor.QueryParams.FILES_UID.key(), file.getUid()) + .append(ClinicalAnalysisDBAdaptor.QueryParams.LOCKED.key(), true); + OpenCGAResult count = clinicalDBAdaptor.count(clinicalQuery); + if (count.getNumMatches() > 0) { + throw new CatalogException("The file " + file.getName() + " is part of " + count.getNumMatches() + " clinical analyses"); + } + + // Check the original files are not being indexed at the moment if (!indexFiles.isEmpty()) { Query query = new Query(FileDBAdaptor.QueryParams.UID.key(), new ArrayList<>(indexFiles)); diff --git a/opencga-catalog/src/test/java/org/opencb/opencga/catalog/managers/FileManagerTest.java b/opencga-catalog/src/test/java/org/opencb/opencga/catalog/managers/FileManagerTest.java index a0517b1294a..d105ba55342 100644 --- a/opencga-catalog/src/test/java/org/opencb/opencga/catalog/managers/FileManagerTest.java +++ b/opencga-catalog/src/test/java/org/opencb/opencga/catalog/managers/FileManagerTest.java @@ -38,11 +38,17 @@ import org.opencb.opencga.catalog.io.IOManager; import org.opencb.opencga.catalog.utils.Constants; import org.opencb.opencga.catalog.utils.ParamUtils; +import org.opencb.opencga.core.common.JacksonUtils; import org.opencb.opencga.core.common.TimeUtils; import org.opencb.opencga.core.common.UriUtils; import org.opencb.opencga.core.models.AclEntryList; +import org.opencb.opencga.core.models.clinical.ClinicalAnalysis; +import org.opencb.opencga.core.models.clinical.ClinicalAnalysisUpdateParams; import org.opencb.opencga.core.models.common.AnnotationSet; +import org.opencb.opencga.core.models.family.Family; import org.opencb.opencga.core.models.file.*; +import org.opencb.opencga.core.models.individual.Individual; +import org.opencb.opencga.core.models.panel.Panel; import org.opencb.opencga.core.models.sample.Sample; import org.opencb.opencga.core.models.study.*; import org.opencb.opencga.core.models.user.Account; @@ -2196,6 +2202,73 @@ public void deleteFolderTest4() throws CatalogException, IOException { } } + @Test + public void deleteFileInClinicalAnalysis() throws CatalogException, IOException { + // START DATA PREPARATION FOR TEST !!! + String bamFile = getClass().getResource("/biofiles/NA19600.chrom20.small.bam").getFile(); + File file = fileManager.link(studyFqn, new FileLinkParams(bamFile, "", "", "", null, null, null, null, null), false, token).first(); + + Family family1 = DummyModelUtils.getDummyFamily("familyId1"); + catalogManager.getFamilyManager().create(studyFqn, family1, QueryOptions.empty(), token); + + // Associate BAM file to sample + String sampleId = family1.getMembers().get(0).getSamples().get(0).getId(); + catalogManager.getFileManager().update(studyFqn, file.getId(), new FileUpdateParams().setSampleIds(Collections.singletonList(sampleId)), + QueryOptions.empty(), token); + + Panel myPanel = DummyModelUtils.getDummyPanel("myPanel"); + catalogManager.getPanelManager().create(studyFqn, myPanel, QueryOptions.empty(), token); + + Family copy = JacksonUtils.copy(family1, Family.class); + for (Individual member : copy.getMembers()) { + // Only use the first sample + member.setSamples(Collections.singletonList(member.getSamples().get(0))); + } + + ClinicalAnalysis clinicalAnalysis1 = DummyModelUtils.getDummyClinicalAnalysis(copy.getMembers().get(0), copy, Collections.singletonList(myPanel)); + clinicalAnalysis1 = catalogManager.getClinicalAnalysisManager().create(studyFqn, clinicalAnalysis1, INCLUDE_RESULT, token).first(); + assertEquals(1, clinicalAnalysis1.getFiles().size()); + assertEquals(file.getPath(), clinicalAnalysis1.getFiles().get(0).getPath()); + assertFalse(clinicalAnalysis1.isLocked()); + + ClinicalAnalysis clinicalAnalysis2 = DummyModelUtils.getDummyClinicalAnalysis(copy.getMembers().get(0), copy, Collections.singletonList(myPanel)); + clinicalAnalysis2 = catalogManager.getClinicalAnalysisManager().create(studyFqn, clinicalAnalysis2, INCLUDE_RESULT, token).first(); + assertEquals(1, clinicalAnalysis2.getFiles().size()); + assertEquals(file.getPath(), clinicalAnalysis2.getFiles().get(0).getPath()); + assertFalse(clinicalAnalysis2.isLocked()); + + // Lock clinicalAnalysis2 + clinicalAnalysis2 = catalogManager.getClinicalAnalysisManager().update(studyFqn, clinicalAnalysis2.getId(), + new ClinicalAnalysisUpdateParams().setLocked(true), INCLUDE_RESULT, token).first(); + assertTrue(clinicalAnalysis2.isLocked()); + // END DATA PREPARATION FOR TEST !!! + + // Mark as pending delete + catalogManager.getFileManager().fileDBAdaptor.update(file.getUid(), new ObjectMap(FileDBAdaptor.QueryParams.INTERNAL_STATUS_ID.key(), FileStatus.PENDING_DELETE), QueryOptions.empty()); + CatalogException catalogException = assertThrows(CatalogException.class, () -> catalogManager.getFileManager().unlink(studyFqn, file.getId(), token)); + assertTrue(catalogException.getMessage().contains("Could not unlink")); + assertTrue(catalogException.getCause().getMessage().contains("clinical analyses")); + + // Unlock clinicalAnalysis2 + clinicalAnalysis2 = catalogManager.getClinicalAnalysisManager().update(studyFqn, clinicalAnalysis2.getId(), + new ClinicalAnalysisUpdateParams().setLocked(false), INCLUDE_RESULT, token).first(); + assertFalse(clinicalAnalysis2.isLocked()); + + // Unlink file + catalogManager.getFileManager().unlink(studyFqn, file.getId(), token); + + Sample sample = catalogManager.getSampleManager().get(studyFqn, sampleId, QueryOptions.empty(), token).first(); + assertEquals(0, sample.getFileIds().size()); + + OpenCGAResult search = catalogManager.getClinicalAnalysisManager().search(studyFqn, new Query(), QueryOptions.empty(), token); + assertEquals(2, search.getNumResults()); + for (ClinicalAnalysis clinicalAnalysis : search.getResults()) { + assertEquals(0, clinicalAnalysis.getFiles().size()); + assertEquals("OPENCGA", clinicalAnalysis.getAudit().get(clinicalAnalysis.getAudit().size() - 1).getAuthor()); + assertTrue(clinicalAnalysis.getAudit().get(clinicalAnalysis.getAudit().size() - 1).getMessage().contains("was deleted. Remove file references from case")); + } + } + private File createBasicDirectoryFileTestEnvironment(List folderFiles) throws CatalogException { File folder = fileManager.createFolder(studyFqn, Paths.get("folder").toString(), false, null, QueryOptions.empty(), token).first(); From b73503d7dde8f7ce18629e87a39abda176b216f7 Mon Sep 17 00:00:00 2001 From: pfurio Date: Fri, 3 May 2024 12:38:58 +0200 Subject: [PATCH 45/85] catalog: remove references from relatedFiles, #TASK-5535 - remove references when a file is deleted/unlinked --- .../opencga/catalog/db/api/FileDBAdaptor.java | 1 + .../db/mongodb/FileMongoDBAdaptor.java | 40 ++++++++++++++++++- .../db/mongodb/converters/FileConverter.java | 2 +- .../opencga/catalog/managers/FileManager.java | 8 ++-- .../catalog/managers/FileManagerTest.java | 26 +++++++++++- 5 files changed, 71 insertions(+), 6 deletions(-) diff --git a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/api/FileDBAdaptor.java b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/api/FileDBAdaptor.java index 86e62f1ebc1..2690fb210ab 100644 --- a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/api/FileDBAdaptor.java +++ b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/api/FileDBAdaptor.java @@ -68,6 +68,7 @@ enum QueryParams implements QueryParam { INTERNAL_STATUS_DESCRIPTION("internal.status.description", TEXT, ""), INTERNAL_STATUS_DATE("internal.status.date", TEXT, ""), RELATED_FILES("relatedFiles", TEXT_ARRAY, ""), + RELATED_FILES_FILE_UID("relatedFiles.file.uid", LONG, ""), RELATED_FILES_RELATION("relatedFiles.relation", TEXT, ""), SIZE("size", INTEGER, ""), EXPERIMENT("experiment", OBJECT, ""), diff --git a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/FileMongoDBAdaptor.java b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/FileMongoDBAdaptor.java index 3b5a14684b4..1cb95b8995a 100644 --- a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/FileMongoDBAdaptor.java +++ b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/FileMongoDBAdaptor.java @@ -40,6 +40,7 @@ import org.opencb.opencga.catalog.managers.FileUtils; import org.opencb.opencga.catalog.managers.SampleManager; import org.opencb.opencga.catalog.utils.Constants; +import org.opencb.opencga.catalog.utils.ParamUtils; import org.opencb.opencga.catalog.utils.ParamUtils.BasicUpdateAction; import org.opencb.opencga.catalog.utils.UuidUtils; import org.opencb.opencga.core.api.ParamConstants; @@ -785,7 +786,8 @@ private UpdateDocument getValidatedUpdateParams(ClientSession clientSession, lon document.getSet().put(QueryParams.RELATED_FILES.key(), relatedFileDocument); break; case REMOVE: - document.getPullAll().put(QueryParams.RELATED_FILES.key(), relatedFileDocument); + List documentList = fixRelatedFilesForRemoval(relatedFileDocument); + document.getPull().put(QueryParams.RELATED_FILES.key(), documentList); break; case ADD: document.getAddToSet().put(QueryParams.RELATED_FILES.key(), relatedFileDocument); @@ -886,6 +888,18 @@ private UpdateDocument getValidatedUpdateParams(ClientSession clientSession, lon return document; } + private List fixRelatedFilesForRemoval(List relatedFiles) { + if (CollectionUtils.isEmpty(relatedFiles)) { + return Collections.emptyList(); + } + + List relatedFilesCopy = new ArrayList<>(relatedFiles.size()); + for (Document relatedFile : relatedFiles) { + relatedFilesCopy.add(new Document("file", new Document("uid", relatedFile.get("file", Document.class).get("uid")))); + } + return relatedFilesCopy; + } + @Override public OpenCGAResult delete(File file) throws CatalogDBException { throw new UnsupportedOperationException("Use delete passing status field."); @@ -1007,6 +1021,7 @@ OpenCGAResult privateDelete(ClientSession clientSession, Document fileDo Document tmpFile = iterator.next(); long tmpFileUid = tmpFile.getLong(PRIVATE_UID); + removeFileReferences(clientSession, studyUid, tmpFileUid, tmpFile); dbAdaptorFactory.getCatalogJobDBAdaptor().removeFileReferences(clientSession, studyUid, tmpFileUid, tmpFile); dbAdaptorFactory.getClinicalAnalysisDBAdaptor().removeFileReferences(clientSession, studyUid, tmpFileUid, tmpFile); @@ -1036,6 +1051,28 @@ OpenCGAResult privateDelete(ClientSession clientSession, Document fileDo } } + void removeFileReferences(ClientSession clientSession, long studyUid, long fileUid, Document fileDoc) + throws CatalogParameterException, CatalogDBException, CatalogAuthorizationException { + File file = fileConverter.convertToDataModelType(fileDoc); + FileRelatedFile relatedFile = new FileRelatedFile(file, null); + ObjectMap parameters = new ObjectMap(QueryParams.RELATED_FILES.key(), Collections.singletonList(relatedFile)); + ObjectMap actionMap = new ObjectMap(QueryParams.RELATED_FILES.key(), ParamUtils.BasicUpdateAction.REMOVE); + QueryOptions options = new QueryOptions(Constants.ACTIONS, actionMap); + + Query query = new Query() + .append(QueryParams.STUDY_UID.key(), studyUid) + .append(QueryParams.RELATED_FILES_FILE_UID.key(), fileUid); + UpdateDocument updateDocument = getValidatedUpdateParams(clientSession, studyUid, parameters, query, options); + Document updateDoc = updateDocument.toFinalUpdateDocument(); + if (!updateDoc.isEmpty()) { + Bson bsonQuery = parseQuery(query); + OpenCGAResult result = transactionalUpdate(clientSession, studyUid, bsonQuery, updateDocument); + if (result.getNumUpdated() > 0) { + logger.debug("File '{}' removed from related files array from {} files.", file.getPath(), result.getNumUpdated()); + } + } + } + // OpenCGAResult privateDelete(ClientSession clientSession, File file, String status) throws CatalogDBException { // long tmpStartTime = startQuery(); // logger.debug("Deleting file {} ({})", file.getPath(), file.getUid()); @@ -1497,6 +1534,7 @@ private Bson parseQuery(Query query, Document extraQuery, String user) case TAGS: case SIZE: case SOFTWARE_NAME: + case RELATED_FILES_FILE_UID: case JOB_ID: addAutoOrQuery(queryParam.key(), queryParam.key(), myQuery, queryParam.type(), andBsonList); break; diff --git a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/converters/FileConverter.java b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/converters/FileConverter.java index 267666f77f0..c4db86b7408 100644 --- a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/converters/FileConverter.java +++ b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/converters/FileConverter.java @@ -107,7 +107,7 @@ public List convertRelatedFiles(List relatedFileList) if (ListUtils.isNotEmpty(relatedFileList)) { for (FileRelatedFile relatedFile : relatedFileList) { relatedFiles.add(new Document() - .append("relation", relatedFile.getRelation().name()) + .append("relation", relatedFile.getRelation() != null ? relatedFile.getRelation().name() : null) .append("file", new Document("uid", relatedFile.getFile().getUid())) ); } diff --git a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/managers/FileManager.java b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/managers/FileManager.java index f1bd98c2a90..2d411253440 100644 --- a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/managers/FileManager.java +++ b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/managers/FileManager.java @@ -1535,7 +1535,7 @@ public OpenCGAResult delete(String studyStr, List fileIds, QueryOptions return delete(studyStr, fileIds, options, false, token); } - public OpenCGAResult delete(String studyStr, List fileIds, ObjectMap params, boolean ignoreException, String token) + public OpenCGAResult delete(String studyStr, List fileIds, QueryOptions options, boolean ignoreException, String token) throws CatalogException { String userId = catalogManager.getUserManager().getUserId(token); Study study = studyManager.resolveId(studyStr, userId, new QueryOptions(QueryOptions.INCLUDE, @@ -1546,13 +1546,15 @@ public OpenCGAResult delete(String studyStr, List fileIds, ObjectMap par ObjectMap auditParams = new ObjectMap() .append("study", studyStr) .append("fileIds", fileIds) - .append("params", params) + .append("options", options) .append("ignoreException", ignoreException) .append("token", token); + QueryOptions queryOptions = options != null ? new QueryOptions(options) : new QueryOptions(); + // We need to avoid processing subfolders or subfiles of an already processed folder independently Set processedPaths = new HashSet<>(); - boolean physicalDelete = params.getBoolean(Constants.SKIP_TRASH, false); + boolean physicalDelete = queryOptions.getBoolean(Constants.SKIP_TRASH, false); auditManager.initAuditBatch(operationUuid); OpenCGAResult result = OpenCGAResult.empty(File.class); diff --git a/opencga-catalog/src/test/java/org/opencb/opencga/catalog/managers/FileManagerTest.java b/opencga-catalog/src/test/java/org/opencb/opencga/catalog/managers/FileManagerTest.java index d105ba55342..c381295d180 100644 --- a/opencga-catalog/src/test/java/org/opencb/opencga/catalog/managers/FileManagerTest.java +++ b/opencga-catalog/src/test/java/org/opencb/opencga/catalog/managers/FileManagerTest.java @@ -1032,7 +1032,7 @@ public void testUnlinkFile() throws CatalogException, IOException { // We send the unlink command again thrown.expect(CatalogException.class); - thrown.expectMessage("not found"); + thrown.expectMessage("not unlink"); fileManager.unlink(studyFqn, "myDirectory/data/test/folder/test_0.5K.txt", token); } @@ -2269,6 +2269,30 @@ public void deleteFileInClinicalAnalysis() throws CatalogException, IOException } } + @Test + public void deleteFileUserInRelatedFilesTest() throws CatalogException { + fileManager.update(studyFqn, "data/test/folder/test_1K.txt.gz", + new FileUpdateParams().setRelatedFiles(Collections.singletonList( + new SmallRelatedFileParams("data/test/folder/test_0.5K.txt", FileRelatedFile.Relation.PART_OF_PAIR))), + null, token); + File file = fileManager.get(studyFqn, "data/test/folder/test_1K.txt.gz", QueryOptions.empty(), token).first(); + assertFalse(file.getRelatedFiles().isEmpty()); + assertEquals(1, file.getRelatedFiles().size()); + assertEquals("data/test/folder/test_0.5K.txt", file.getRelatedFiles().get(0).getFile().getPath()); + + file = fileManager.get(studyFqn, "data/test/folder/test_0.5K.txt", FileManager.INCLUDE_FILE_IDS, token).first(); + + // Mark as pending delete + catalogManager.getFileManager().fileDBAdaptor.update(file.getUid(), new ObjectMap(FileDBAdaptor.QueryParams.INTERNAL_STATUS_ID.key(), FileStatus.PENDING_DELETE), QueryOptions.empty()); + // Delete test_0.5K file + QueryOptions options = new QueryOptions(Constants.SKIP_TRASH, true); + fileManager.delete(studyFqn, Collections.singletonList("data/test/folder/test_0.5K.txt"), options, token); + + // Ensure there are no more references to test_0.5K file + file = fileManager.get(studyFqn, "data/test/folder/test_1K.txt.gz", QueryOptions.empty(), token).first(); + assertTrue(file.getRelatedFiles().isEmpty()); + } + private File createBasicDirectoryFileTestEnvironment(List folderFiles) throws CatalogException { File folder = fileManager.createFolder(studyFqn, Paths.get("folder").toString(), false, null, QueryOptions.empty(), token).first(); From bb19f7548291867606a4fd2a5adf3a97b5a47f1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacobo=20Coll=20Morag=C3=B3n?= Date: Fri, 3 May 2024 22:54:07 +0100 Subject: [PATCH 46/85] storage: Add migration to detect invalid files and samples. #TASK-6078 --- ...llegalConcurrentFileLoadingsMigration.java | 265 ++++++++++++++++++ .../exceptions/StorageEngineException.java | 5 + .../VariantStorageMetadataManager.java | 12 +- .../adaptors/FileMetadataDBAdaptor.java | 4 - .../core/metadata/models/TaskMetadata.java | 6 + .../core/variant/VariantStoragePipeline.java | 12 +- .../adaptors/VariantQueryException.java | 4 + .../variant/query/VariantQueryParser.java | 14 + .../SampleIndexVariantQueryExecutor.java | 2 +- .../index/sample/SampleIndexQueryParser.java | 2 +- ...doopVariantStorageEngineSplitDataTest.java | 80 ++++++ 11 files changed, 395 insertions(+), 11 deletions(-) create mode 100644 opencga-app/src/main/java/org/opencb/opencga/app/migrations/v2_12_5/storage/DetectIllegalConcurrentFileLoadingsMigration.java diff --git a/opencga-app/src/main/java/org/opencb/opencga/app/migrations/v2_12_5/storage/DetectIllegalConcurrentFileLoadingsMigration.java b/opencga-app/src/main/java/org/opencb/opencga/app/migrations/v2_12_5/storage/DetectIllegalConcurrentFileLoadingsMigration.java new file mode 100644 index 00000000000..68a40c4901e --- /dev/null +++ b/opencga-app/src/main/java/org/opencb/opencga/app/migrations/v2_12_5/storage/DetectIllegalConcurrentFileLoadingsMigration.java @@ -0,0 +1,265 @@ +package org.opencb.opencga.app.migrations.v2_12_5.storage; + +import org.opencb.commons.datastore.core.ObjectMap; +import org.opencb.commons.datastore.core.Query; +import org.opencb.commons.datastore.core.QueryOptions; +import org.opencb.opencga.app.migrations.StorageMigrationTool; +import org.opencb.opencga.catalog.db.api.FileDBAdaptor; +import org.opencb.opencga.catalog.exceptions.CatalogException; +import org.opencb.opencga.catalog.migration.Migration; +import org.opencb.opencga.core.common.TimeUtils; +import org.opencb.opencga.core.common.UriUtils; +import org.opencb.opencga.core.models.file.File; +import org.opencb.opencga.storage.core.exceptions.StorageEngineException; +import org.opencb.opencga.storage.core.metadata.VariantStorageMetadataManager; +import org.opencb.opencga.storage.core.metadata.models.FileMetadata; +import org.opencb.opencga.storage.core.metadata.models.SampleMetadata; +import org.opencb.opencga.storage.core.metadata.models.TaskMetadata; +import org.opencb.opencga.storage.core.variant.VariantStorageEngine; +import org.opencb.opencga.storage.core.variant.adaptors.GenotypeClass; +import org.opencb.opencga.storage.core.variant.adaptors.VariantField; +import org.opencb.opencga.storage.core.variant.adaptors.VariantQuery; + +import java.time.Instant; +import java.util.*; +import java.util.stream.Collectors; + +@Migration(id = "illegal_concurrent_file_loadings" , + description = "Detect illegal concurrent file loadings and fix them by setting 'status' to 'INVALID' or 'READY'", + version = "2.12.5", + manual = true, + domain = Migration.MigrationDomain.STORAGE, + language = Migration.MigrationLanguage.JAVA, + date = 20240424 +) +public class DetectIllegalConcurrentFileLoadingsMigration extends StorageMigrationTool { + + @Override + protected void run() throws Exception { + for (String project : getVariantStorageProjects()) { + VariantStorageEngine engine = getVariantStorageEngineByProject(project); + if (!engine.getStorageEngineId().equals("hadoop")) { + continue; + } + logger.info("Checking project '{}'", project); + for (String study : engine.getMetadataManager().getStudyNames()) { + checkStudy(engine, study); + } + } + } + + private void checkStudy(VariantStorageEngine engine, String study) throws StorageEngineException, CatalogException { + VariantStorageMetadataManager metadataManager = engine.getMetadataManager(); + + logger.info("Checking study '{}'", study); + int studyId = metadataManager.getStudyId(study); + + Set> fileSets = getFileWithSharedSamples(engine, studyId); + Set fileIds = fileSets.stream().flatMap(Collection::stream).collect(Collectors.toSet()); + + if (fileSets.isEmpty()) { + logger.info("No concurrent file loadings found in study '{}'", study); + return; + } + + Map fileTasks = new HashMap<>(); + for (TaskMetadata taskMetadata : metadataManager.taskIterable(studyId)) { + if (taskMetadata.getType() == TaskMetadata.Type.LOAD) { + for (Integer fileId : taskMetadata.getFileIds()) { + if (fileIds.contains(fileId)) { + TaskMetadata old = fileTasks.put(fileId, taskMetadata); + if (old != null) { + throw new IllegalStateException("File '" + fileId + "' is being loaded by more than one task." + + " Tasks '" + old.getName() + "'(" + old.getId() + ") and" + + " '" + taskMetadata.getName() + "'(" + taskMetadata.getId() + ")"); + } + } + } + } + } + + Set> fileSetsToInvalidate = new HashSet<>(); + Set affectedFiles = new HashSet<>(); + Set affectedSamples = new HashSet<>(); + for (Set fileSet : fileSets) { + // Check if any task from this file set overlaps in time + List tasks = new ArrayList<>(); + for (Integer fileId : fileSet) { + TaskMetadata task = fileTasks.get(fileId); + if (task != null) { + tasks.add(task); + } + } + if (tasks.size() > 1) { + logger.info("Found {} tasks loading files {}", tasks.size(), fileSet); + for (int i = 0; i < tasks.size(); i++) { + TaskMetadata task1 = tasks.get(i); + Date task1start = task1.getStatus().firstKey(); + Date task1end = task1.getStatus().lastKey(); + for (int f = i + 1; f < tasks.size(); f++) { + TaskMetadata task2 = tasks.get(f); + Date task2start = task2.getStatus().firstKey(); + Date task2end = task2.getStatus().lastKey(); + if (task1start.before(task2end) && task1end.after(task2start)) { + fileSetsToInvalidate.add(fileSet); + affectedFiles.addAll(task1.getFileIds()); + + List task1Files = task1.getFileIds().stream().map(fileId -> "'" + metadataManager.getFileName(studyId, fileId) + "'(" + fileId + ")").collect(Collectors.toList()); + List task2Files = task2.getFileIds().stream().map(fileId -> "'" + metadataManager.getFileName(studyId, fileId) + "'(" + fileId + ")").collect(Collectors.toList()); + + logger.info("Tasks '{}'({}) and '{}'({}) overlap in time", task1.getName(), task1.getId(), task2.getName(), task2.getId()); + logger.info("Task1: {} - {} loading files {}", task1start, task1end, task1Files); + logger.info("Task2: {} - {} loading files {}", task2start, task2end, task2Files); + Set task1Samples = task1.getFileIds().stream().flatMap(file -> metadataManager.getSampleIdsFromFileId(studyId, file).stream()).collect(Collectors.toSet()); + Set task2Samples = task2.getFileIds().stream().flatMap(file -> metadataManager.getSampleIdsFromFileId(studyId, file).stream()).collect(Collectors.toSet()); + for (Integer task1Sample : task1Samples) { + if (task2Samples.contains(task1Sample)) { + String sampleName = metadataManager.getSampleName(studyId, task1Sample); + affectedSamples.add(task1Sample); + logger.info("Sample '{}'({}) is shared between tasks", sampleName, task1Sample); + } + } + } + } + } + } + + Set invalidFiles = new HashSet<>(); + List invalidSampleIndexes = new ArrayList<>(); + for (Integer sampleId : affectedSamples) { + String sampleName = metadataManager.getSampleName(studyId, sampleId); + SampleMetadata sampleMetadata = metadataManager.getSampleMetadata(studyId, sampleId); + if (!sampleMetadata.isMultiFileSample()) { + logger.warn("Sample '{}'({}) is not a multi-file sample but has multiple files loaded", sampleName, sampleId); + for (Integer file : sampleMetadata.getFiles()) { + if (metadataManager.isFileIndexed(studyId, file)) { + invalidFiles.add(file); + logger.info(" - Invalidating file '{}'({}). Must be deleted and then indexed.", + metadataManager.getFileName(studyId, file), file); + } + } + } else if (sampleMetadata.getSampleIndexStatus(sampleMetadata.getSampleIndexVersion()) == TaskMetadata.Status.READY) { + for (Integer fileId : sampleMetadata.getFiles()) { + if (affectedFiles.contains(fileId)) { + FileMetadata fileMetadata = metadataManager.getFileMetadata(studyId, fileId); + String fileName = fileMetadata.getName(); + + long actualCount = engine.get(new VariantQuery().study(study).sample(sampleName).file(fileName), + new QueryOptions(QueryOptions.INCLUDE, VariantField.ID).append(QueryOptions.COUNT, true)) + .getNumMatches(); + + File catalogFile = catalogManager.getFileManager().search(study, + new Query(FileDBAdaptor.QueryParams.URI.key(), UriUtils.createUriSafe(fileMetadata.getPath())), + new QueryOptions(), token).first(); + if (catalogFile == null) { + logger.warn("File '{}'({}) not found in catalog", fileName, fileId); + logger.warn("Sample '{}'({}) invalidated, as file '{}'({}) is not found in catalog", sampleName, sampleId, fileName, fileId); + logger.info(" - Invalidating sample index for sample '{}'({})", sampleName, sampleId); + invalidSampleIndexes.add(sampleId); + continue; + } + if (fileMetadata.getSamples().size() == 1) { + long expectedCount = 0; + for (Map.Entry entry : catalogFile.getQualityControl().getVariant() + .getVariantSetMetrics().getGenotypeCount().entrySet()) { + if (GenotypeClass.MAIN_ALT.test(entry.getKey())) { + expectedCount += entry.getValue(); + } + } + if (expectedCount == 0) { + expectedCount = catalogFile.getQualityControl().getVariant().getVariantSetMetrics().getVariantCount(); + } + if (expectedCount != actualCount) { + invalidSampleIndexes.add(sampleId); + logger.warn("Sample '{}'({}) was expected to have {} variants in the sample index of file '{}'({}) but has {}", + sampleName, sampleId, fileName, fileId, expectedCount, actualCount); + logger.info(" - Invalidating sample index for sample '{}'({})", sampleName, sampleId); + } + } else { + Map pipelineResult = (Map) catalogFile.getAttributes().get("storagePipelineResult"); + long loadedVariants = ((Number) ((Map) pipelineResult.get("loadStats")).get("loadedVariants")).longValue(); + if (loadedVariants != actualCount) { + invalidSampleIndexes.add(sampleId); + logger.warn("Sample '{}'({}) was expected to have {} variants in the sample index but has {}", + sampleName, sampleId, loadedVariants, actualCount); + logger.info(" - Invalidating sample index for sample '{}'({})", sampleName, sampleId); + } + } + } + } + } else { + invalidSampleIndexes.add(sampleId); + } + } + + if (params.getBoolean("dry-run")) { + logger.info("Dry-run mode. Skipping invalidation of files and samples"); + } else { + ObjectMap event = new ObjectMap() + .append("patch", getAnnotation().patch()) + .append("description", "affected_invalid_sample") + .append("dateStr", TimeUtils.getTime()) + .append("date", Date.from(Instant.now())); + for (Integer sampleId : invalidSampleIndexes) { + metadataManager.updateSampleMetadata(studyId, sampleId, sampleMetadata -> { + if (sampleMetadata.getAttributes().containsKey("TASK-6078")) { + logger.info("Sample '{}'({}) already has the attribute 'TASK-6078'. Skip", sampleMetadata.getName(), sampleMetadata.getId()); + } else { + for (Integer sampleIndexVersion : sampleMetadata.getSampleIndexVersions()) { + sampleMetadata.setSampleIndexStatus(TaskMetadata.Status.NONE, sampleIndexVersion); + } + sampleMetadata.getAttributes().put("TASK-6078", event); + } + }); + } + Set invalidSamples = new HashSet<>(); + for (Integer fileId : invalidFiles) { + metadataManager.updateFileMetadata(studyId, fileId, fileMetadata -> { + invalidSamples.addAll(fileMetadata.getSamples()); + if (fileMetadata.getAttributes().containsKey("TASK-6078")) { + logger.info("File '{}'({}) already has the attribute 'TASK-6078'. Skip", fileMetadata.getName(), fileMetadata.getId()); + } else { + fileMetadata.setIndexStatus(TaskMetadata.Status.INVALID); + fileMetadata.getAttributes().put("TASK-6078", event); + } + }); + } + for (Integer sampleId : invalidSamples) { + metadataManager.updateSampleMetadata(studyId, sampleId, sampleMetadata -> { + if (sampleMetadata.getAttributes().containsKey("TASK-6078")) { + logger.info("Sample '{}'({}) already has the attribute 'TASK-6078'. Skip", sampleMetadata.getName(), sampleMetadata.getId()); + } else { + sampleMetadata.setIndexStatus(TaskMetadata.Status.INVALID); + sampleMetadata.getAttributes().put("TASK-6078", event); + } + }); + } + } + } + } + + private Set> getFileWithSharedSamples(VariantStorageEngine engine, int studyId) throws StorageEngineException { + VariantStorageMetadataManager metadataManager = engine.getMetadataManager(); + + Set> fileSets = new HashSet<>(); + // Check if there are any sample with more than one file + for (SampleMetadata sampleMetadata : metadataManager.sampleMetadataIterable(studyId)) { + if (sampleMetadata.getFiles().size() > 1) { + if (sampleMetadata.getSplitData() == VariantStorageEngine.SplitData.CHROMOSOME || sampleMetadata.getSplitData() == VariantStorageEngine.SplitData.REGION) { + logger.debug("Sample '{}' is split by chromosome or region. Skip", sampleMetadata.getName()); + continue; + } + ArrayList sampleFileIds = new ArrayList<>(sampleMetadata.getFiles()); + + sampleFileIds.removeIf(fileId -> !metadataManager.isFileIndexed(studyId, fileId)); + + if (sampleFileIds.size() > 1) { + logger.info("Sample '{}' has more than one indexed file with split data '{}'", sampleMetadata.getName(), sampleMetadata.getSplitData()); + + fileSets.add(new HashSet<>(sampleFileIds)); + } + } + } + return fileSets; + } +} diff --git a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/exceptions/StorageEngineException.java b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/exceptions/StorageEngineException.java index 547b83c55af..0ac128118a9 100644 --- a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/exceptions/StorageEngineException.java +++ b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/exceptions/StorageEngineException.java @@ -41,6 +41,11 @@ public static StorageEngineException alreadyLoaded(int fileId, String fileName) return unableToExecute("Already loaded", fileId, fileName); } + public static StorageEngineException invalidFileStatus(int fileId, String fileName) { + return unableToExecute("File is in INVALID status. Unable to load. File needs to be deleted from the variant-storage", + fileId, fileName); + } + public static StorageEngineException otherOperationInProgressException(TaskMetadata operation, String jobOperationName, List fileIds, VariantStorageMetadataManager mm) { diff --git a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/metadata/VariantStorageMetadataManager.java b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/metadata/VariantStorageMetadataManager.java index 3f863d4b680..34dcec280ed 100644 --- a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/metadata/VariantStorageMetadataManager.java +++ b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/metadata/VariantStorageMetadataManager.java @@ -679,6 +679,7 @@ public FileMetadata updateFileMetadata(int studyId, int fi update.update(fileMetadata); lock.checkLocked(); unsecureUpdateFileMetadata(studyId, fileMetadata); + fileIdIndexedCache.put(studyId, fileId, fileMetadata.isIndexed()); return fileMetadata; } finally { lock.unlock(); @@ -807,7 +808,6 @@ public void addIndexedFiles(int studyId, List fileIds) throws StorageEn .getName(); logger.info("Register file " + name + " as INDEXED"); } - fileDBAdaptor.addIndexedFiles(studyId, fileIds); fileIdsFromSampleIdCache.clear(); fileIdIndexedCache.clear(); } @@ -821,6 +821,7 @@ public void removeIndexedFiles(int studyId, Collection fileIds) throws fileMetadata.setIndexStatus(TaskMetadata.Status.NONE); fileMetadata.setSecondaryAnnotationIndexStatus(TaskMetadata.Status.NONE); fileMetadata.setAnnotationStatus(TaskMetadata.Status.NONE); + fileMetadata.getAttributes().remove(LOAD_ARCHIVE.key()); if (fileMetadata.getType() == FileMetadata.Type.VIRTUAL) { partialFiles.addAll(fileMetadata.getAttributes().getAsIntegerList(FileMetadata.VIRTUAL_FILES)); } @@ -833,6 +834,7 @@ public void removeIndexedFiles(int studyId, Collection fileIds) throws fileMetadata.setIndexStatus(TaskMetadata.Status.NONE); fileMetadata.setSecondaryAnnotationIndexStatus(TaskMetadata.Status.NONE); fileMetadata.setAnnotationStatus(TaskMetadata.Status.NONE); + fileMetadata.getAttributes().remove(LOAD_ARCHIVE.key()); }); // deleteVariantFileMetadata(studyId, fileId); } @@ -851,7 +853,6 @@ public void removeIndexedFiles(int studyId, Collection fileIds) throws } }); } - fileDBAdaptor.removeIndexedFiles(studyId, fileIds); } public Iterable fileMetadataIterable(int studyId) { @@ -1278,6 +1279,10 @@ public TaskMetadata getTask(int studyId, String taskName, List fileIds) return task; } + public Iterable taskIterable(int studyId) { + return () -> taskIterator(studyId, null, false); + } + public Iterator taskIterator(int studyId) { return taskIterator(studyId, null, false); } @@ -1754,6 +1759,9 @@ private int registerFile(int studyId, String filePath, FileMetadata.Type type) t if (fileId != null) { updateFileMetadata(studyId, fileId, fileMetadata -> { + if (fileMetadata.getIndexStatus() == TaskMetadata.Status.INVALID) { + throw StorageEngineException.invalidFileStatus(fileMetadata.getId(), fileName); + } if (fileMetadata.isIndexed()) { throw StorageEngineException.alreadyLoaded(fileMetadata.getId(), fileName); } diff --git a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/metadata/adaptors/FileMetadataDBAdaptor.java b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/metadata/adaptors/FileMetadataDBAdaptor.java index ca6a5964b59..8cb916df1c6 100644 --- a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/metadata/adaptors/FileMetadataDBAdaptor.java +++ b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/metadata/adaptors/FileMetadataDBAdaptor.java @@ -75,10 +75,6 @@ public String description() { LinkedHashSet getIndexedFiles(int studyId, boolean includePartial); - default void addIndexedFiles(int studyId, List fileIds) {} - - default void removeIndexedFiles(int studyId, Collection fileIds) {}; - default DataResult count() { return count(new Query()); } diff --git a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/metadata/models/TaskMetadata.java b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/metadata/models/TaskMetadata.java index aba5d230c88..c0d0cf9376c 100644 --- a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/metadata/models/TaskMetadata.java +++ b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/metadata/models/TaskMetadata.java @@ -61,6 +61,12 @@ public enum Status { * Any needed clean might be executed by other running tasks */ ABORTED, + /** + * Finished. + * Task finished with invalid results. + * Similar to "ERROR" status, but this can't be resumed. Needs to be cleaned first. + */ + INVALID, } public enum Type { diff --git a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/VariantStoragePipeline.java b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/VariantStoragePipeline.java index 19b0631659f..5b37d2512b1 100644 --- a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/VariantStoragePipeline.java +++ b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/VariantStoragePipeline.java @@ -61,6 +61,7 @@ import org.opencb.opencga.storage.core.io.plain.StringDataWriter; import org.opencb.opencga.storage.core.metadata.VariantStorageMetadataManager; import org.opencb.opencga.storage.core.metadata.models.CohortMetadata; +import org.opencb.opencga.storage.core.metadata.models.FileMetadata; import org.opencb.opencga.storage.core.metadata.models.StudyMetadata; import org.opencb.opencga.storage.core.metadata.models.TaskMetadata; import org.opencb.opencga.storage.core.variant.adaptors.GenotypeClass; @@ -176,9 +177,14 @@ public URI preTransform(URI input) throws StorageEngineException, IOException, F Integer fileId = getMetadataManager().getFileId(studyMetadata.getId(), fileName, true); if (fileId != null) { // File is indexed. Mark as non indexed. - getMetadataManager().updateFileMetadata(studyMetadata.getId(), fileId, fileMetadata -> { - fileMetadata.setIndexStatus(TaskMetadata.Status.NONE); - }); + FileMetadata fileMetadata = getMetadataManager().getFileMetadata(studyMetadata.getId(), fileId); + if (fileMetadata.getIndexStatus() == TaskMetadata.Status.INVALID) { + throw StorageEngineException.invalidFileStatus(fileId, fileName); + } else if (fileMetadata.getIndexStatus() != TaskMetadata.Status.NONE) { + getMetadataManager().updateFileMetadata(studyMetadata.getId(), fileId, fm -> { + fm.setIndexStatus(TaskMetadata.Status.NONE); + }); + } logger.info("File '{}' already loaded. Force reload!", fileName); } } diff --git a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/adaptors/VariantQueryException.java b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/adaptors/VariantQueryException.java index d90698f9e44..20ef94c7f2c 100644 --- a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/adaptors/VariantQueryException.java +++ b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/adaptors/VariantQueryException.java @@ -217,6 +217,10 @@ public static VariantQueryException fileNotFound(Object file, Object study) { return new VariantQueryException("File " + quote(file) + " not found in study '" + study + "'"); } + public static VariantQueryException fileNotIndexed(Object file, Object study) { + return new VariantQueryException("File " + quote(file) + " not indexed in study '" + study + "'"); + } + public static VariantQueryException scoreNotFound(Object score, Object study) { return new VariantQueryException("Variant Score " + quote(score) + " not found in study '" + study + "'"); } diff --git a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/VariantQueryParser.java b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/VariantQueryParser.java index a0f641fa987..641e365a51d 100644 --- a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/VariantQueryParser.java +++ b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/VariantQueryParser.java @@ -3,6 +3,7 @@ import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.EnumUtils; import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.tuple.Pair; import org.opencb.biodata.models.core.Region; import org.opencb.biodata.models.variant.StudyEntry; import org.opencb.biodata.models.variant.Variant; @@ -459,6 +460,19 @@ protected void preProcessStudyParams(Query query, QueryOptions options, VariantQ } } + if (isValidParam(query, FILE)) { + ParsedQuery files = splitValue(query, FILE); + for (String file : files.getValues()) { + Pair fileIdPair = metadataManager.getFileIdPair(file, false, defaultStudy); + if (fileIdPair == null) { + throw VariantQueryException.fileNotFound(file, defaultStudy.getName()); + } + if (!metadataManager.isFileIndexed(fileIdPair.getKey(), fileIdPair.getValue())) { + throw VariantQueryException.fileNotIndexed(file, metadataManager.getStudyName(fileIdPair.getKey())); + } + } + } + QueryOperation genotypeOperator = null; VariantQueryParam genotypeParam = null; diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/index/SampleIndexVariantQueryExecutor.java b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/index/SampleIndexVariantQueryExecutor.java index 25cb7052acd..6175128018d 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/index/SampleIndexVariantQueryExecutor.java +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/index/SampleIndexVariantQueryExecutor.java @@ -191,7 +191,7 @@ private boolean queryFiltersCovered(Query query) { // Check if the query is fully covered Set params = VariantQueryUtils.validParams(query, true); params.remove(VariantQueryParam.STUDY); - + logger.info("Uncovered filters : " + params); return params.isEmpty(); } diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/index/sample/SampleIndexQueryParser.java b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/index/sample/SampleIndexQueryParser.java index 08bfd820c72..6137c5bd6c1 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/index/sample/SampleIndexQueryParser.java +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/index/sample/SampleIndexQueryParser.java @@ -274,7 +274,7 @@ public SampleIndexQuery parse(Query query) { //} else if (isValidParam(query, FILE)) { // Add FILEs filter ? } else { - throw new IllegalStateException("Unable to query SamplesIndex"); + throw new IllegalStateException("Unable to query SamplesIndex. Missing sample filter! Query: " + query.toJson()); } boolean requireFamilyIndex = !mendelianErrorSet.isEmpty(); SampleIndexSchema schema = schemaFactory.getSchema(studyId, sampleGenotypeQuery.keySet(), false, requireFamilyIndex); diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/test/java/org/opencb/opencga/storage/hadoop/variant/HadoopVariantStorageEngineSplitDataTest.java b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/test/java/org/opencb/opencga/storage/hadoop/variant/HadoopVariantStorageEngineSplitDataTest.java index c8bd80e1882..e4f1f2e14b4 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/test/java/org/opencb/opencga/storage/hadoop/variant/HadoopVariantStorageEngineSplitDataTest.java +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/test/java/org/opencb/opencga/storage/hadoop/variant/HadoopVariantStorageEngineSplitDataTest.java @@ -16,6 +16,7 @@ import org.opencb.commons.datastore.core.Query; import org.opencb.commons.datastore.core.QueryOptions; import org.opencb.opencga.core.api.ParamConstants; +import org.opencb.opencga.core.common.UriUtils; import org.opencb.opencga.core.testclassification.duration.LongTests; import org.opencb.opencga.storage.core.StoragePipelineResult; import org.opencb.opencga.storage.core.exceptions.StorageEngineException; @@ -30,6 +31,7 @@ import org.opencb.opencga.storage.core.variant.VariantStoragePipeline; import org.opencb.opencga.storage.core.variant.adaptors.VariantField; import org.opencb.opencga.storage.core.variant.adaptors.VariantQuery; +import org.opencb.opencga.storage.core.variant.adaptors.VariantQueryException; import org.opencb.opencga.storage.core.variant.adaptors.VariantQueryParam; import org.opencb.opencga.storage.core.variant.adaptors.iterators.VariantDBIterator; import org.opencb.opencga.storage.core.variant.annotation.annotators.CellBaseRestVariantAnnotator; @@ -689,6 +691,84 @@ private VariantStorageEngine getMockedStorageEngine(ObjectMap options) throws Ex return mockedStorageEngine; } + @Test + public void testDeleteErrorFiles() throws Exception { + URI outDir = newOutputUri(); + + VariantStorageMetadataManager mm = variantStorageEngine.getMetadataManager(); + + variantStorageEngine.getOptions().put(VariantStorageOptions.STUDY.key(), STUDY_NAME); + URI file = variantStorageEngine.index(Collections.singletonList(getPlatinumFile(1)), outDir).get(0).getInput(); + String fileName = UriUtils.fileName(file); + + int studyId = mm.getStudyId(STUDY_NAME); + int fileId = mm.getFileId(studyId, fileName); + FileMetadata fileMetadata = mm.updateFileMetadata(studyId, fileId, fm -> { + fm.setIndexStatus(TaskMetadata.Status.INVALID); + }); + assertFalse(mm.isFileIndexed(studyId, fileId)); + assertFalse(fileMetadata.isIndexed()); + LinkedHashSet samples = fileMetadata.getSamples(); + + for (Integer sample : samples) { + mm.updateSampleMetadata(studyId, sample, sampleMetadata -> { + sampleMetadata.setIndexStatus(TaskMetadata.Status.INVALID); + }); + } + + try { + variantStorageEngine.get(new VariantQuery().file(fileName), new QueryOptions()); + fail(); + } catch (VariantQueryException e) { + String expected = VariantQueryException.fileNotIndexed(fileName, STUDY_NAME).getMessage(); + assertEquals(expected, e.getMessage()); + } + + try { + variantStorageEngine.getOptions().put(VariantStorageOptions.FORCE.key(), true); + variantStorageEngine.index(Collections.singletonList(getPlatinumFile(1)), outDir); + fail(); + } catch (StorageEngineException e) { + try { + String expected = StorageEngineException.invalidFileStatus(fileId, fileName).getMessage(); + assertEquals(expected, e.getCause().getMessage()); + } catch (AssertionError error) { + e.printStackTrace(); + throw error; + } + } + + try { + variantStorageEngine.getOptions().put(VariantStorageOptions.FORCE.key(), false); + variantStorageEngine.index(Collections.singletonList(getPlatinumFile(1)), outDir); + fail(); + } catch (StorageEngineException e) { + try { + String expected = StorageEngineException.invalidFileStatus(fileId, fileName).getMessage(); + assertEquals(expected, e.getCause().getMessage()); + } catch (AssertionError error) { + e.printStackTrace(); + throw error; + } + } + + variantStorageEngine.removeFile(STUDY_NAME, fileName, outDir); + + fileMetadata = mm.getFileMetadata(studyId, fileId); + assertEquals(TaskMetadata.Status.NONE, fileMetadata.getIndexStatus()); + for (Integer sample : samples) { + assertEquals(TaskMetadata.Status.NONE, mm.getSampleMetadata(studyId, sample).getIndexStatus()); + } + + variantStorageEngine.index(Collections.singletonList(getPlatinumFile(1)), outDir); + + fileMetadata = mm.getFileMetadata(studyId, fileId); + assertEquals(TaskMetadata.Status.READY, fileMetadata.getIndexStatus()); + for (Integer sample : samples) { + assertEquals(TaskMetadata.Status.READY, mm.getSampleMetadata(studyId, sample).getIndexStatus()); + } + } + @Test public void testLoadByRegion() throws Exception { URI outDir = newOutputUri(); From 68a9561438d584dab17f220348fc44ab73f13245 Mon Sep 17 00:00:00 2001 From: JuanfeSanahuja Date: Mon, 6 May 2024 12:41:16 +0200 Subject: [PATCH 47/85] MailUtils:FIX: Code scanning/SonarCloud - Server hostnames should be verified during SSL/TLS connections #TASK-464 --- .../src/main/java/org/opencb/opencga/core/common/MailUtils.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/opencga-core/src/main/java/org/opencb/opencga/core/common/MailUtils.java b/opencga-core/src/main/java/org/opencb/opencga/core/common/MailUtils.java index 7ff75f86698..e180538aa7f 100644 --- a/opencga-core/src/main/java/org/opencb/opencga/core/common/MailUtils.java +++ b/opencga-core/src/main/java/org/opencb/opencga/core/common/MailUtils.java @@ -45,7 +45,9 @@ public static void sendResetPasswordMail(String to, String newPassword, final St props.put("mail.smtp.starttls.enable", "true"); props.put("mail.smtp.starttls.required", "true"); props.put("mail.smtp.ssl.protocols", "TLSv1.2"); + props.put("mail.smtp.ssl.checkserveridentity", "true"); props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory"); + Session session = Session.getInstance(props, new javax.mail.Authenticator() { protected PasswordAuthentication getPasswordAuthentication() { From f8b7020de9a4f8ce0728554bfefe4d95e7fb995b Mon Sep 17 00:00:00 2001 From: JuanfeSanahuja Date: Mon, 6 May 2024 19:49:05 +0200 Subject: [PATCH 48/85] pom: Create hot fix branch #TASK-6172 --- opencga-analysis/pom.xml | 2 +- opencga-app/pom.xml | 2 +- opencga-catalog/pom.xml | 2 +- opencga-client/pom.xml | 2 +- opencga-clinical/pom.xml | 2 +- opencga-core/pom.xml | 2 +- opencga-master/pom.xml | 2 +- opencga-server/pom.xml | 2 +- opencga-storage/opencga-storage-app/pom.xml | 2 +- opencga-storage/opencga-storage-benchmark/pom.xml | 2 +- opencga-storage/opencga-storage-core/pom.xml | 2 +- .../opencga-storage-hadoop/opencga-storage-hadoop-core/pom.xml | 2 +- .../opencga-storage-hadoop-deps-emr6.1/pom.xml | 2 +- .../opencga-storage-hadoop-deps-hdp2.6/pom.xml | 2 +- .../opencga-storage-hadoop-deps-hdp3.1/pom.xml | 2 +- .../opencga-storage-hadoop/opencga-storage-hadoop-deps/pom.xml | 2 +- opencga-storage/opencga-storage-hadoop/pom.xml | 2 +- opencga-storage/opencga-storage-server/pom.xml | 2 +- opencga-storage/pom.xml | 2 +- opencga-test/pom.xml | 2 +- pom.xml | 2 +- 21 files changed, 21 insertions(+), 21 deletions(-) diff --git a/opencga-analysis/pom.xml b/opencga-analysis/pom.xml index b9dfad55dc4..36890fd8b65 100644 --- a/opencga-analysis/pom.xml +++ b/opencga-analysis/pom.xml @@ -22,7 +22,7 @@ org.opencb.opencga opencga - 2.12.4 + 2.12.4.1-SNAPSHOT ../pom.xml diff --git a/opencga-app/pom.xml b/opencga-app/pom.xml index 4a1ed3c2907..cce6a1832f6 100644 --- a/opencga-app/pom.xml +++ b/opencga-app/pom.xml @@ -22,7 +22,7 @@ org.opencb.opencga opencga - 2.12.4 + 2.12.4.1-SNAPSHOT ../pom.xml diff --git a/opencga-catalog/pom.xml b/opencga-catalog/pom.xml index 7a0a54910ce..fa4d079fca2 100644 --- a/opencga-catalog/pom.xml +++ b/opencga-catalog/pom.xml @@ -23,7 +23,7 @@ org.opencb.opencga opencga - 2.12.4 + 2.12.4.1-SNAPSHOT ../pom.xml diff --git a/opencga-client/pom.xml b/opencga-client/pom.xml index 797cdbcaabd..cf8bce68061 100644 --- a/opencga-client/pom.xml +++ b/opencga-client/pom.xml @@ -22,7 +22,7 @@ org.opencb.opencga opencga - 2.12.4 + 2.12.4.1-SNAPSHOT ../pom.xml diff --git a/opencga-clinical/pom.xml b/opencga-clinical/pom.xml index 3deebdfe00c..5e87374579c 100644 --- a/opencga-clinical/pom.xml +++ b/opencga-clinical/pom.xml @@ -5,7 +5,7 @@ org.opencb.opencga opencga - 2.12.4 + 2.12.4.1-SNAPSHOT ../pom.xml 4.0.0 diff --git a/opencga-core/pom.xml b/opencga-core/pom.xml index d1bce7dd255..b896c8ef333 100644 --- a/opencga-core/pom.xml +++ b/opencga-core/pom.xml @@ -22,7 +22,7 @@ org.opencb.opencga opencga - 2.12.4 + 2.12.4.1-SNAPSHOT ../pom.xml diff --git a/opencga-master/pom.xml b/opencga-master/pom.xml index 555b40fd93c..0e14a74b9a2 100644 --- a/opencga-master/pom.xml +++ b/opencga-master/pom.xml @@ -22,7 +22,7 @@ opencga org.opencb.opencga - 2.12.4 + 2.12.4.1-SNAPSHOT ../pom.xml diff --git a/opencga-server/pom.xml b/opencga-server/pom.xml index 00cd35d1974..255d0d1709c 100644 --- a/opencga-server/pom.xml +++ b/opencga-server/pom.xml @@ -22,7 +22,7 @@ org.opencb.opencga opencga - 2.12.4 + 2.12.4.1-SNAPSHOT ../pom.xml diff --git a/opencga-storage/opencga-storage-app/pom.xml b/opencga-storage/opencga-storage-app/pom.xml index b50473c3dea..f2834ff74ae 100644 --- a/opencga-storage/opencga-storage-app/pom.xml +++ b/opencga-storage/opencga-storage-app/pom.xml @@ -22,7 +22,7 @@ org.opencb.opencga opencga-storage - 2.12.4 + 2.12.4.1-SNAPSHOT ../pom.xml diff --git a/opencga-storage/opencga-storage-benchmark/pom.xml b/opencga-storage/opencga-storage-benchmark/pom.xml index 237df394693..81ae1525c3e 100644 --- a/opencga-storage/opencga-storage-benchmark/pom.xml +++ b/opencga-storage/opencga-storage-benchmark/pom.xml @@ -22,7 +22,7 @@ opencga-storage org.opencb.opencga - 2.12.4 + 2.12.4.1-SNAPSHOT ../pom.xml diff --git a/opencga-storage/opencga-storage-core/pom.xml b/opencga-storage/opencga-storage-core/pom.xml index a78bc108cd3..83ba931c476 100644 --- a/opencga-storage/opencga-storage-core/pom.xml +++ b/opencga-storage/opencga-storage-core/pom.xml @@ -22,7 +22,7 @@ org.opencb.opencga opencga-storage - 2.12.4 + 2.12.4.1-SNAPSHOT ../pom.xml diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/pom.xml b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/pom.xml index ae1663ed408..0cb400c03d3 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/pom.xml +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/pom.xml @@ -23,7 +23,7 @@ org.opencb.opencga opencga-storage-hadoop - 2.12.4 + 2.12.4.1-SNAPSHOT ../pom.xml diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-deps/opencga-storage-hadoop-deps-emr6.1/pom.xml b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-deps/opencga-storage-hadoop-deps-emr6.1/pom.xml index 299f46d55e1..be258210e4f 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-deps/opencga-storage-hadoop-deps-emr6.1/pom.xml +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-deps/opencga-storage-hadoop-deps-emr6.1/pom.xml @@ -22,7 +22,7 @@ org.opencb.opencga opencga-storage-hadoop-deps - 2.12.4 + 2.12.4.1-SNAPSHOT ../pom.xml diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-deps/opencga-storage-hadoop-deps-hdp2.6/pom.xml b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-deps/opencga-storage-hadoop-deps-hdp2.6/pom.xml index d39f818fa65..7ce0441a47d 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-deps/opencga-storage-hadoop-deps-hdp2.6/pom.xml +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-deps/opencga-storage-hadoop-deps-hdp2.6/pom.xml @@ -22,7 +22,7 @@ org.opencb.opencga opencga-storage-hadoop-deps - 2.12.4 + 2.12.4.1-SNAPSHOT ../pom.xml diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-deps/opencga-storage-hadoop-deps-hdp3.1/pom.xml b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-deps/opencga-storage-hadoop-deps-hdp3.1/pom.xml index c80452c7b80..cf4bb3c0833 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-deps/opencga-storage-hadoop-deps-hdp3.1/pom.xml +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-deps/opencga-storage-hadoop-deps-hdp3.1/pom.xml @@ -22,7 +22,7 @@ org.opencb.opencga opencga-storage-hadoop-deps - 2.12.4 + 2.12.4.1-SNAPSHOT ../pom.xml diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-deps/pom.xml b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-deps/pom.xml index fb5c1500b27..a2124179531 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-deps/pom.xml +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-deps/pom.xml @@ -50,7 +50,7 @@ org.opencb.opencga opencga-storage-hadoop - 2.12.4 + 2.12.4.1-SNAPSHOT ../pom.xml diff --git a/opencga-storage/opencga-storage-hadoop/pom.xml b/opencga-storage/opencga-storage-hadoop/pom.xml index eb724763958..364447c5d26 100644 --- a/opencga-storage/opencga-storage-hadoop/pom.xml +++ b/opencga-storage/opencga-storage-hadoop/pom.xml @@ -28,7 +28,7 @@ org.opencb.opencga opencga-storage - 2.12.4 + 2.12.4.1-SNAPSHOT ../pom.xml diff --git a/opencga-storage/opencga-storage-server/pom.xml b/opencga-storage/opencga-storage-server/pom.xml index 4927f1d5263..d07a2556ef6 100644 --- a/opencga-storage/opencga-storage-server/pom.xml +++ b/opencga-storage/opencga-storage-server/pom.xml @@ -22,7 +22,7 @@ org.opencb.opencga opencga-storage - 2.12.4 + 2.12.4.1-SNAPSHOT ../pom.xml diff --git a/opencga-storage/pom.xml b/opencga-storage/pom.xml index 5796b008eed..8af319c168b 100644 --- a/opencga-storage/pom.xml +++ b/opencga-storage/pom.xml @@ -22,7 +22,7 @@ org.opencb.opencga opencga - 2.12.4 + 2.12.4.1-SNAPSHOT ../pom.xml diff --git a/opencga-test/pom.xml b/opencga-test/pom.xml index 0840b6813d5..fd776c8408b 100644 --- a/opencga-test/pom.xml +++ b/opencga-test/pom.xml @@ -24,7 +24,7 @@ org.opencb.opencga opencga - 2.12.4 + 2.12.4.1-SNAPSHOT ../pom.xml diff --git a/pom.xml b/pom.xml index 893c4f54869..bd0b2b56ab6 100644 --- a/pom.xml +++ b/pom.xml @@ -22,7 +22,7 @@ org.opencb.opencga opencga - 2.12.4 + 2.12.4.1-SNAPSHOT pom OpenCGA From cc9f2ca2cfeb0f0c52d6535b778ac0e0fe67402e Mon Sep 17 00:00:00 2001 From: pfurio Date: Tue, 7 May 2024 15:55:40 +0200 Subject: [PATCH 49/85] catalog: enable mail as a valid user id, #TASK-6183 --- .../main/java/org/opencb/opencga/catalog/utils/ParamUtils.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/utils/ParamUtils.java b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/utils/ParamUtils.java index 7d6eb326acc..f9351c4b27e 100644 --- a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/utils/ParamUtils.java +++ b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/utils/ParamUtils.java @@ -124,7 +124,7 @@ public static void checkValidUserId(String userId) throws CatalogParameterExcept if (userId.equals(ParamConstants.ANONYMOUS_USER_ID) || userId.equals(ParamConstants.REGISTERED_USERS)) { throw new CatalogParameterException("User id cannot be one of the reserved OpenCGA users."); } - if (!userId.matches("^[A-Za-z0-9]([-_.]?[A-Za-z0-9])*$")) { + if (!userId.matches("^[A-Za-z0-9]([-_.@]?[A-Za-z0-9])*$")) { throw new CatalogParameterException("Invalid user id. Id needs to start by any character and might contain single '-', '_', " + "'.', symbols followed by any character or number."); } From 7b655a76b1cc09909f1806187393fd8ae8870cab Mon Sep 17 00:00:00 2001 From: pfurio Date: Tue, 7 May 2024 15:56:48 +0200 Subject: [PATCH 50/85] catalog: fix error message, #TASK-6183 --- .../main/java/org/opencb/opencga/catalog/utils/ParamUtils.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/utils/ParamUtils.java b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/utils/ParamUtils.java index f9351c4b27e..c39d111d8c7 100644 --- a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/utils/ParamUtils.java +++ b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/utils/ParamUtils.java @@ -126,7 +126,7 @@ public static void checkValidUserId(String userId) throws CatalogParameterExcept } if (!userId.matches("^[A-Za-z0-9]([-_.@]?[A-Za-z0-9])*$")) { throw new CatalogParameterException("Invalid user id. Id needs to start by any character and might contain single '-', '_', " - + "'.', symbols followed by any character or number."); + + "'.' or '@' symbols followed by any character or number."); } } From da7eff0b698883e0c71595ec2b08e1536011cd25 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacobo=20Coll=20Morag=C3=B3n?= Date: Mon, 6 May 2024 11:43:48 +0100 Subject: [PATCH 51/85] app: Small improvements to migration. #TASK-6078 --- ...llegalConcurrentFileLoadingsMigration.java | 30 ++++++++++++++----- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/opencga-app/src/main/java/org/opencb/opencga/app/migrations/v2_12_5/storage/DetectIllegalConcurrentFileLoadingsMigration.java b/opencga-app/src/main/java/org/opencb/opencga/app/migrations/v2_12_5/storage/DetectIllegalConcurrentFileLoadingsMigration.java index 68a40c4901e..bf69842c07d 100644 --- a/opencga-app/src/main/java/org/opencb/opencga/app/migrations/v2_12_5/storage/DetectIllegalConcurrentFileLoadingsMigration.java +++ b/opencga-app/src/main/java/org/opencb/opencga/app/migrations/v2_12_5/storage/DetectIllegalConcurrentFileLoadingsMigration.java @@ -138,7 +138,7 @@ private void checkStudy(VariantStorageEngine engine, String study) throws Storag metadataManager.getFileName(studyId, file), file); } } - } else if (sampleMetadata.getSampleIndexStatus(sampleMetadata.getSampleIndexVersion()) == TaskMetadata.Status.READY) { + } else if (sampleMetadata.getSampleIndexStatus(Optional.of(sampleMetadata.getSampleIndexVersion()).orElse(-1)) == TaskMetadata.Status.READY) { for (Integer fileId : sampleMetadata.getFiles()) { if (affectedFiles.contains(fileId)) { FileMetadata fileMetadata = metadataManager.getFileMetadata(studyId, fileId); @@ -158,7 +158,7 @@ private void checkStudy(VariantStorageEngine engine, String study) throws Storag invalidSampleIndexes.add(sampleId); continue; } - if (fileMetadata.getSamples().size() == 1) { + if (fileMetadata.getSamples().size() == 1 && catalogFile.getSampleIds().size() == 1) { long expectedCount = 0; for (Map.Entry entry : catalogFile.getQualityControl().getVariant() .getVariantSetMetrics().getGenotypeCount().entrySet()) { @@ -172,7 +172,7 @@ private void checkStudy(VariantStorageEngine engine, String study) throws Storag if (expectedCount != actualCount) { invalidSampleIndexes.add(sampleId); logger.warn("Sample '{}'({}) was expected to have {} variants in the sample index of file '{}'({}) but has {}", - sampleName, sampleId, fileName, fileId, expectedCount, actualCount); + sampleName, sampleId, expectedCount, fileName, fileId, actualCount); logger.info(" - Invalidating sample index for sample '{}'({})", sampleName, sampleId); } } else { @@ -193,7 +193,20 @@ private void checkStudy(VariantStorageEngine engine, String study) throws Storag } if (params.getBoolean("dry-run")) { - logger.info("Dry-run mode. Skipping invalidation of files and samples"); + if (invalidFiles.isEmpty() && invalidSampleIndexes.isEmpty()) { + logger.info("Dry-run mode. No files or samples to invalidate"); + } else { + logger.info("Dry-run mode. Skipping invalidation of files and samples"); + + Set invalidSamples = new HashSet<>(); + for (Integer fileId : invalidFiles) { + invalidSamples.addAll(metadataManager.getSampleIdsFromFileId(studyId, fileId)); + } + + logger.info("Affected files: {}", invalidFiles); + logger.info("Affected samples: {}", invalidSamples); + logger.info("Affected sample indexes: {}", invalidSampleIndexes); + } } else { ObjectMap event = new ObjectMap() .append("patch", getAnnotation().patch()) @@ -205,10 +218,11 @@ private void checkStudy(VariantStorageEngine engine, String study) throws Storag if (sampleMetadata.getAttributes().containsKey("TASK-6078")) { logger.info("Sample '{}'({}) already has the attribute 'TASK-6078'. Skip", sampleMetadata.getName(), sampleMetadata.getId()); } else { + Map oldStatus = new HashMap<>(sampleMetadata.getStatus()); for (Integer sampleIndexVersion : sampleMetadata.getSampleIndexVersions()) { sampleMetadata.setSampleIndexStatus(TaskMetadata.Status.NONE, sampleIndexVersion); } - sampleMetadata.getAttributes().put("TASK-6078", event); + sampleMetadata.getAttributes().put("TASK-6078", new ObjectMap(event).append("oldStatus", oldStatus)); } }); } @@ -219,8 +233,9 @@ private void checkStudy(VariantStorageEngine engine, String study) throws Storag if (fileMetadata.getAttributes().containsKey("TASK-6078")) { logger.info("File '{}'({}) already has the attribute 'TASK-6078'. Skip", fileMetadata.getName(), fileMetadata.getId()); } else { + Map oldStatus = new HashMap<>(fileMetadata.getStatus()); fileMetadata.setIndexStatus(TaskMetadata.Status.INVALID); - fileMetadata.getAttributes().put("TASK-6078", event); + fileMetadata.getAttributes().put("TASK-6078", new ObjectMap(event).append("oldStatus", oldStatus)); } }); } @@ -229,8 +244,9 @@ private void checkStudy(VariantStorageEngine engine, String study) throws Storag if (sampleMetadata.getAttributes().containsKey("TASK-6078")) { logger.info("Sample '{}'({}) already has the attribute 'TASK-6078'. Skip", sampleMetadata.getName(), sampleMetadata.getId()); } else { + Map oldStatus = new HashMap<>(sampleMetadata.getStatus()); sampleMetadata.setIndexStatus(TaskMetadata.Status.INVALID); - sampleMetadata.getAttributes().put("TASK-6078", event); + sampleMetadata.getAttributes().put("TASK-6078", new ObjectMap(event).append("oldStatus", oldStatus)); } }); } From bed4579418ea97586efdfa1d00c5e167f8a9df32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacobo=20Coll=20Morag=C3=B3n?= Date: Tue, 7 May 2024 15:18:57 +0100 Subject: [PATCH 52/85] app: Store migration event in catalog as well. #TASK-6078 --- ...llegalConcurrentFileLoadingsMigration.java | 29 +++++++++++++------ 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/opencga-app/src/main/java/org/opencb/opencga/app/migrations/v2_12_5/storage/DetectIllegalConcurrentFileLoadingsMigration.java b/opencga-app/src/main/java/org/opencb/opencga/app/migrations/v2_12_5/storage/DetectIllegalConcurrentFileLoadingsMigration.java index bf69842c07d..d64a3163715 100644 --- a/opencga-app/src/main/java/org/opencb/opencga/app/migrations/v2_12_5/storage/DetectIllegalConcurrentFileLoadingsMigration.java +++ b/opencga-app/src/main/java/org/opencb/opencga/app/migrations/v2_12_5/storage/DetectIllegalConcurrentFileLoadingsMigration.java @@ -10,6 +10,8 @@ import org.opencb.opencga.core.common.TimeUtils; import org.opencb.opencga.core.common.UriUtils; import org.opencb.opencga.core.models.file.File; +import org.opencb.opencga.core.models.file.FileUpdateParams; +import org.opencb.opencga.core.models.sample.SampleUpdateParams; import org.opencb.opencga.storage.core.exceptions.StorageEngineException; import org.opencb.opencga.storage.core.metadata.VariantStorageMetadataManager; import org.opencb.opencga.storage.core.metadata.models.FileMetadata; @@ -214,7 +216,8 @@ private void checkStudy(VariantStorageEngine engine, String study) throws Storag .append("dateStr", TimeUtils.getTime()) .append("date", Date.from(Instant.now())); for (Integer sampleId : invalidSampleIndexes) { - metadataManager.updateSampleMetadata(studyId, sampleId, sampleMetadata -> { + ObjectMap thisEvent = new ObjectMap(event); + String sampleName = metadataManager.updateSampleMetadata(studyId, sampleId, sampleMetadata -> { if (sampleMetadata.getAttributes().containsKey("TASK-6078")) { logger.info("Sample '{}'({}) already has the attribute 'TASK-6078'. Skip", sampleMetadata.getName(), sampleMetadata.getId()); } else { @@ -222,33 +225,41 @@ private void checkStudy(VariantStorageEngine engine, String study) throws Storag for (Integer sampleIndexVersion : sampleMetadata.getSampleIndexVersions()) { sampleMetadata.setSampleIndexStatus(TaskMetadata.Status.NONE, sampleIndexVersion); } - sampleMetadata.getAttributes().put("TASK-6078", new ObjectMap(event).append("oldStatus", oldStatus)); + sampleMetadata.getAttributes().put("TASK-6078", thisEvent.append("oldStatus", oldStatus)); } - }); + }).getName(); + catalogManager.getSampleManager().update(study, sampleName, + new SampleUpdateParams().setAttributes(new ObjectMap("TASK-6078", thisEvent)), QueryOptions.empty(), token); } Set invalidSamples = new HashSet<>(); for (Integer fileId : invalidFiles) { - metadataManager.updateFileMetadata(studyId, fileId, fileMetadata -> { + ObjectMap thisEvent = new ObjectMap(event); + String filePath = metadataManager.updateFileMetadata(studyId, fileId, fileMetadata -> { invalidSamples.addAll(fileMetadata.getSamples()); if (fileMetadata.getAttributes().containsKey("TASK-6078")) { logger.info("File '{}'({}) already has the attribute 'TASK-6078'. Skip", fileMetadata.getName(), fileMetadata.getId()); } else { Map oldStatus = new HashMap<>(fileMetadata.getStatus()); fileMetadata.setIndexStatus(TaskMetadata.Status.INVALID); - fileMetadata.getAttributes().put("TASK-6078", new ObjectMap(event).append("oldStatus", oldStatus)); + fileMetadata.getAttributes().put("TASK-6078", thisEvent.append("oldStatus", oldStatus)); } - }); + }).getPath(); + catalogManager.getFileManager().update(study, filePath, + new FileUpdateParams().setAttributes(new ObjectMap("TASK-6078", thisEvent)), QueryOptions.empty(), token); } for (Integer sampleId : invalidSamples) { - metadataManager.updateSampleMetadata(studyId, sampleId, sampleMetadata -> { + ObjectMap thisEvent = new ObjectMap(event); + String sampleName = metadataManager.updateSampleMetadata(studyId, sampleId, sampleMetadata -> { if (sampleMetadata.getAttributes().containsKey("TASK-6078")) { logger.info("Sample '{}'({}) already has the attribute 'TASK-6078'. Skip", sampleMetadata.getName(), sampleMetadata.getId()); } else { Map oldStatus = new HashMap<>(sampleMetadata.getStatus()); sampleMetadata.setIndexStatus(TaskMetadata.Status.INVALID); - sampleMetadata.getAttributes().put("TASK-6078", new ObjectMap(event).append("oldStatus", oldStatus)); + sampleMetadata.getAttributes().put("TASK-6078", thisEvent.append("oldStatus", oldStatus)); } - }); + }).getName(); + catalogManager.getSampleManager().update(study, sampleName, + new SampleUpdateParams().setAttributes(new ObjectMap("TASK-6078", thisEvent)), QueryOptions.empty(), token); } } } From 9c9e09cc341e5ce2cc2347d5e80e90a3ac64b109 Mon Sep 17 00:00:00 2001 From: imedina Date: Tue, 7 May 2024 01:02:17 +0100 Subject: [PATCH 53/85] storage: add modified HGVS and pharmacogenomics to 'xrefs' #TASK-6172 --- .../VariantAnnotationModelUtils.java | 66 +++++++++++++++---- 1 file changed, 53 insertions(+), 13 deletions(-) diff --git a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/annotation/converters/VariantAnnotationModelUtils.java b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/annotation/converters/VariantAnnotationModelUtils.java index c31b7137236..8e71ac5b53b 100644 --- a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/annotation/converters/VariantAnnotationModelUtils.java +++ b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/annotation/converters/VariantAnnotationModelUtils.java @@ -6,6 +6,8 @@ import java.util.HashSet; import java.util.List; import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; public class VariantAnnotationModelUtils { @@ -21,19 +23,24 @@ public class VariantAnnotationModelUtils { * - annotation.consequenceTypes.transcriptId * - annotation.consequenceTypes.ensemblTranscriptId * - annotation.consequenceTypes.hgvs + * - annotation.consequenceTypes.proteinVariantAnnotation.proteinId * - annotation.consequenceTypes.proteinVariantAnnotation.uniprotAccession * - annotation.consequenceTypes.proteinVariantAnnotation.uniprotName * - annotation.consequenceTypes.proteinVariantAnnotation.uniprotVariantId * - annotation.consequenceTypes.proteinVariantAnnotation.features.id * - annotation.traitAssociation.id - * - annotation.geneTraitAssociation.hpo * - annotation.geneTraitAssociation.id + * - annotation.geneTraitAssociation.hpo + * - annotation.pharmacogenomics.id + * - annotation.pharmacogenomics.name * * @param variantAnnotation VariantAnnotation object * @return Set of XRefs */ + private static final Pattern HGVS_PATTERN = Pattern.compile("\\([^()]*\\)"); + public Set extractXRefs(VariantAnnotation variantAnnotation) { - Set xrefs = new HashSet<>(); + Set xrefs = new HashSet<>(100); if (variantAnnotation == null) { return xrefs; @@ -41,7 +48,7 @@ public Set extractXRefs(VariantAnnotation variantAnnotation) { xrefs.add(variantAnnotation.getId()); - if (variantAnnotation.getXrefs() != null) { + if (CollectionUtils.isNotEmpty(variantAnnotation.getXrefs())) { for (Xref xref : variantAnnotation.getXrefs()) { if (xref != null) { xrefs.add(xref.getId()); @@ -49,26 +56,53 @@ public Set extractXRefs(VariantAnnotation variantAnnotation) { } } - if (variantAnnotation.getHgvs() != null) { + if (CollectionUtils.isNotEmpty(variantAnnotation.getHgvs())) { xrefs.addAll(variantAnnotation.getHgvs()); + + // TODO Remove this code when CellBase 6.4.0 returns the expected HGVS + for (String hgvs: variantAnnotation.getHgvs()) { + if (hgvs.startsWith("ENST") || hgvs.startsWith("NM_")) { + // 1. Remove the content between parentheses, e.g. ENST00000680783.1(ENSG00000135744):c.776T>C + if (hgvs.contains("(")) { + Matcher matcher = HGVS_PATTERN.matcher(hgvs); + StringBuffer result = new StringBuffer(); + while (matcher.find()) { + matcher.appendReplacement(result, ""); + } + matcher.appendTail(result); + xrefs.add(result.toString()); + } + + // 2. Add the HGVS with the Ensembl and gene name, e.g. ENSG00000135744:c.776T>C, AGT:c.776T>C + for (ConsequenceType conseqType : variantAnnotation.getConsequenceTypes()) { + if (conseqType != null && conseqType.getHgvs().contains(hgvs)) { + String[] fields = hgvs.split(":"); + xrefs.add(conseqType.getGeneId() + ":" + fields[1]); + xrefs.add(conseqType.getGeneName() + ":" + fields[1]); + break; + } + } + } + } } List consequenceTypes = variantAnnotation.getConsequenceTypes(); - if (consequenceTypes != null) { + if (CollectionUtils.isNotEmpty(consequenceTypes)) { for (ConsequenceType conseqType : consequenceTypes) { xrefs.add(conseqType.getGeneName()); xrefs.add(conseqType.getGeneId()); - xrefs.add(conseqType.getEnsemblGeneId()); xrefs.add(conseqType.getTranscriptId()); + xrefs.add(conseqType.getEnsemblGeneId()); xrefs.add(conseqType.getEnsemblTranscriptId()); - if (conseqType.getHgvs() != null) { - xrefs.addAll(conseqType.getHgvs()); - } + // This is already added in the variantAnnotation.getHgvs() section +// if (conseqType.getHgvs() != null) { +// xrefs.addAll(conseqType.getHgvs()); +// } ProteinVariantAnnotation protVarAnnotation = conseqType.getProteinVariantAnnotation(); if (protVarAnnotation != null) { - + xrefs.add(protVarAnnotation.getProteinId()); xrefs.add(protVarAnnotation.getUniprotAccession()); xrefs.add(protVarAnnotation.getUniprotName()); xrefs.add(protVarAnnotation.getUniprotVariantId()); @@ -80,7 +114,6 @@ public Set extractXRefs(VariantAnnotation variantAnnotation) { } } } - } if (CollectionUtils.isNotEmpty(variantAnnotation.getTraitAssociation())) { @@ -89,10 +122,17 @@ public Set extractXRefs(VariantAnnotation variantAnnotation) { } } - if (variantAnnotation.getGeneTraitAssociation() != null) { + if (CollectionUtils.isNotEmpty(variantAnnotation.getGeneTraitAssociation())) { for (GeneTraitAssociation geneTrait : variantAnnotation.getGeneTraitAssociation()) { - xrefs.add(geneTrait.getHpo()); xrefs.add(geneTrait.getId()); + xrefs.add(geneTrait.getHpo()); + } + } + + if (CollectionUtils.isNotEmpty(variantAnnotation.getPharmacogenomics())) { + for (Pharmacogenomics pharmacogenomics : variantAnnotation.getPharmacogenomics()) { + xrefs.add(pharmacogenomics.getId()); + xrefs.add(pharmacogenomics.getName()); } } From 4451b13d21f0bced909291076801ca690c96288c Mon Sep 17 00:00:00 2001 From: pfurio Date: Tue, 7 May 2024 16:53:59 +0200 Subject: [PATCH 54/85] catalog: add mail test, #TASK-6183 --- .../opencga/catalog/managers/CatalogManagerTest.java | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/opencga-catalog/src/test/java/org/opencb/opencga/catalog/managers/CatalogManagerTest.java b/opencga-catalog/src/test/java/org/opencb/opencga/catalog/managers/CatalogManagerTest.java index 8e468806d04..2b403314f4a 100644 --- a/opencga-catalog/src/test/java/org/opencb/opencga/catalog/managers/CatalogManagerTest.java +++ b/opencga-catalog/src/test/java/org/opencb/opencga/catalog/managers/CatalogManagerTest.java @@ -49,6 +49,7 @@ import org.opencb.opencga.core.models.sample.*; import org.opencb.opencga.core.models.study.*; import org.opencb.opencga.core.models.user.Account; +import org.opencb.opencga.core.models.user.AuthenticationResponse; import org.opencb.opencga.core.models.user.User; import org.opencb.opencga.core.response.OpenCGAResult; import org.opencb.opencga.core.testclassification.duration.MediumTests; @@ -276,6 +277,16 @@ private String getAdminToken() throws CatalogException, IOException { return catalogManager.getUserManager().loginAsAdmin("admin").getToken(); } + @Test + public void createUserUsingMailAsId() throws CatalogException { + catalogManager.getUserManager().create(new User().setId("hello.mail@mymail.org").setName("Hello") + .setAccount(new Account().setType(Account.AccountType.GUEST)), TestParamConstants.PASSWORD, opencgaToken); + AuthenticationResponse login = catalogManager.getUserManager().login("hello.mail@mymail.org", TestParamConstants.PASSWORD); + assertNotNull(login); + User user = catalogManager.getUserManager().get("hello.mail@mymail.org", new QueryOptions(), login.getToken()).first(); + assertEquals("hello.mail@mymail.org", user.getId()); + } + @Test public void getGroupsTest() throws CatalogException { Group group = new Group("groupId", Arrays.asList("user2", "user3")).setSyncedFrom(new Group.Sync("ldap", "bio")); From 3b8f89015a30bd52ac77ecbf94f053e9d5556a55 Mon Sep 17 00:00:00 2001 From: JuanfeSanahuja Date: Tue, 7 May 2024 16:58:00 +0200 Subject: [PATCH 55/85] MailUtils: Change user_id to CamelCase #TASK-464 --- .../main/java/org/opencb/opencga/core/common/MailUtils.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/opencga-core/src/main/java/org/opencb/opencga/core/common/MailUtils.java b/opencga-core/src/main/java/org/opencb/opencga/core/common/MailUtils.java index e180538aa7f..ef5852befa8 100644 --- a/opencga-core/src/main/java/org/opencb/opencga/core/common/MailUtils.java +++ b/opencga-core/src/main/java/org/opencb/opencga/core/common/MailUtils.java @@ -35,7 +35,7 @@ public class MailUtils { private static final Logger logger = LoggerFactory.getLogger(MailUtils.class); public static void sendResetPasswordMail(String to, String newPassword, final String mailUser, final String mailPassword, - String mailHost, String mailPort, String ssl, String user_id) throws Exception { + String mailHost, String mailPort, String ssl, String userId) throws Exception { Properties props = new Properties(); props.put("mail.smtp.auth", "true"); @@ -61,7 +61,7 @@ protected PasswordAuthentication getPasswordAuthentication() { InternetAddress.parse(to)); message.setSubject("XetaBase: Password Reset"); - message.setText(getEmailContent(user_id,newPassword)); + message.setText(getEmailContent(userId,newPassword)); Transport.send(message); } From d5101a45e91d67f1ef79f300c9622de24333faf7 Mon Sep 17 00:00:00 2001 From: JuanfeSanahuja Date: Tue, 7 May 2024 17:56:56 +0200 Subject: [PATCH 56/85] MailUtils: Refactor ssl and userId variables #TASK-464 --- .../auth/authentication/CatalogAuthenticationManager.java | 3 +-- .../java/org/opencb/opencga/core/common/MailUtils.java | 8 +++++--- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/auth/authentication/CatalogAuthenticationManager.java b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/auth/authentication/CatalogAuthenticationManager.java index d86d778a1e2..88b807edd3e 100644 --- a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/auth/authentication/CatalogAuthenticationManager.java +++ b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/auth/authentication/CatalogAuthenticationManager.java @@ -133,8 +133,7 @@ public OpenCGAResult resetPassword(String userId) throws CatalogException { String mailHost = this.emailConfig.getHost(); String mailPort = this.emailConfig.getPort(); try { - MailUtils.sendResetPasswordMail(email, newPassword, mailUser, mailPassword, mailHost, mailPort, - "true", ((User) user.getResults().get(0)).getId()); + MailUtils.sendResetPasswordMail(email, newPassword, mailUser, mailPassword, mailHost, mailPort, userId); result = userDBAdaptor.resetPassword(userId, email, newPassword); } catch (Exception e) { throw new CatalogException("Email could not be sent.", e); diff --git a/opencga-core/src/main/java/org/opencb/opencga/core/common/MailUtils.java b/opencga-core/src/main/java/org/opencb/opencga/core/common/MailUtils.java index ef5852befa8..1802d54a642 100644 --- a/opencga-core/src/main/java/org/opencb/opencga/core/common/MailUtils.java +++ b/opencga-core/src/main/java/org/opencb/opencga/core/common/MailUtils.java @@ -34,14 +34,16 @@ public class MailUtils { private static final Logger logger = LoggerFactory.getLogger(MailUtils.class); + + public static void sendResetPasswordMail(String to, String newPassword, final String mailUser, final String mailPassword, - String mailHost, String mailPort, String ssl, String userId) throws Exception { + String mailHost, String mailPort, String userId) throws Exception { Properties props = new Properties(); - props.put("mail.smtp.auth", "true"); - props.put("mail.smtp.ssl.enable", ssl); props.put("mail.smtp.host", mailHost); props.put("mail.smtp.port", mailPort); + props.put("mail.smtp.auth", "true"); + props.put("mail.smtp.ssl.enable", "true"); props.put("mail.smtp.starttls.enable", "true"); props.put("mail.smtp.starttls.required", "true"); props.put("mail.smtp.ssl.protocols", "TLSv1.2"); From 364e0a6043be646f951fbcb9f489cf04d09f474d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacobo=20Coll=20Morag=C3=B3n?= Date: Tue, 7 May 2024 17:01:23 +0100 Subject: [PATCH 57/85] storage: Add test to query by alternative hgvs forms #TASK-6172 --- .../VariantAnnotationModelUtils.java | 24 ++++++---- .../core/variant/query/VariantQueryUtils.java | 13 ++++++ .../VariantAnnotationModelUtilsTest.java | 46 +++++++++++++++++++ .../executors/VariantQueryExecutorTest.java | 6 +++ 4 files changed, 81 insertions(+), 8 deletions(-) create mode 100644 opencga-storage/opencga-storage-core/src/test/java/org/opencb/opencga/storage/core/variant/annotation/converters/VariantAnnotationModelUtilsTest.java diff --git a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/annotation/converters/VariantAnnotationModelUtils.java b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/annotation/converters/VariantAnnotationModelUtils.java index 8e71ac5b53b..b6c8bfcf39d 100644 --- a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/annotation/converters/VariantAnnotationModelUtils.java +++ b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/annotation/converters/VariantAnnotationModelUtils.java @@ -2,6 +2,7 @@ import org.apache.commons.collections4.CollectionUtils; import org.opencb.biodata.models.variant.avro.*; +import org.opencb.opencga.storage.core.variant.query.VariantQueryUtils; import java.util.HashSet; import java.util.List; @@ -56,12 +57,14 @@ public Set extractXRefs(VariantAnnotation variantAnnotation) { } } + List consequenceTypes = variantAnnotation.getConsequenceTypes(); + if (CollectionUtils.isNotEmpty(variantAnnotation.getHgvs())) { xrefs.addAll(variantAnnotation.getHgvs()); // TODO Remove this code when CellBase 6.4.0 returns the expected HGVS for (String hgvs: variantAnnotation.getHgvs()) { - if (hgvs.startsWith("ENST") || hgvs.startsWith("NM_")) { + if (VariantQueryUtils.isTranscript(hgvs)) { // 1. Remove the content between parentheses, e.g. ENST00000680783.1(ENSG00000135744):c.776T>C if (hgvs.contains("(")) { Matcher matcher = HGVS_PATTERN.matcher(hgvs); @@ -74,19 +77,24 @@ public Set extractXRefs(VariantAnnotation variantAnnotation) { } // 2. Add the HGVS with the Ensembl and gene name, e.g. ENSG00000135744:c.776T>C, AGT:c.776T>C - for (ConsequenceType conseqType : variantAnnotation.getConsequenceTypes()) { - if (conseqType != null && conseqType.getHgvs().contains(hgvs)) { - String[] fields = hgvs.split(":"); - xrefs.add(conseqType.getGeneId() + ":" + fields[1]); - xrefs.add(conseqType.getGeneName() + ":" + fields[1]); - break; + if (CollectionUtils.isNotEmpty(consequenceTypes)) { + for (ConsequenceType conseqType : consequenceTypes) { + if (conseqType != null && conseqType.getHgvs() != null && conseqType.getHgvs().contains(hgvs)) { + String[] fields = hgvs.split(":", 2); + if (conseqType.getGeneId() != null) { + xrefs.add(conseqType.getGeneId() + ":" + fields[1]); + } + if (conseqType.getGeneName() != null) { + xrefs.add(conseqType.getGeneName() + ":" + fields[1]); + } + break; + } } } } } } - List consequenceTypes = variantAnnotation.getConsequenceTypes(); if (CollectionUtils.isNotEmpty(consequenceTypes)) { for (ConsequenceType conseqType : consequenceTypes) { xrefs.add(conseqType.getGeneName()); diff --git a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/VariantQueryUtils.java b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/VariantQueryUtils.java index a538092ef4f..e57462b5561 100644 --- a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/VariantQueryUtils.java +++ b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/VariantQueryUtils.java @@ -467,6 +467,19 @@ public static boolean isVariantAccession(String value) { return value.startsWith("rs") || value.startsWith("VAR_"); } + /** + * Determines if the given value might be a known transcript or not. + * Ensembl transcripts start with `ENST` + * RefSeq transcripts start with `NM_` + * See ... + * + * @param value Value to check + * @return If is a known transcript + */ + public static boolean isTranscript(String value) { + return value.startsWith("ENST") || value.startsWith("NM_"); + } + /** * Determines if the given value is a HGVS. * diff --git a/opencga-storage/opencga-storage-core/src/test/java/org/opencb/opencga/storage/core/variant/annotation/converters/VariantAnnotationModelUtilsTest.java b/opencga-storage/opencga-storage-core/src/test/java/org/opencb/opencga/storage/core/variant/annotation/converters/VariantAnnotationModelUtilsTest.java new file mode 100644 index 00000000000..f1167213be9 --- /dev/null +++ b/opencga-storage/opencga-storage-core/src/test/java/org/opencb/opencga/storage/core/variant/annotation/converters/VariantAnnotationModelUtilsTest.java @@ -0,0 +1,46 @@ +package org.opencb.opencga.storage.core.variant.annotation.converters; + +import junit.framework.TestCase; +import org.junit.experimental.categories.Category; +import org.opencb.biodata.models.variant.avro.ConsequenceType; +import org.opencb.biodata.models.variant.avro.VariantAnnotation; +import org.opencb.biodata.models.variant.avro.Xref; +import org.opencb.opencga.core.testclassification.duration.ShortTests; + +import java.util.Arrays; +import java.util.Collections; +import java.util.Set; + +@Category(ShortTests.class) +public class VariantAnnotationModelUtilsTest extends TestCase { + + public void testXrefsHgvs() throws Exception { + VariantAnnotation variantAnnotation = new VariantAnnotation(); + variantAnnotation.setId("id"); + variantAnnotation.setXrefs(Collections.singletonList(new Xref("xref1", "source"))); + variantAnnotation.setHgvs(Arrays.asList( + "ENST00000680783.1(ENSG00000135744):c.776T>C", + "ENSP00000451720.1:p.Asn134Lys" + )); + ConsequenceType ct = new ConsequenceType(); + ct.setGeneName("GENE"); + ct.setHgvs(variantAnnotation.getHgvs()); + ct.setGeneId(null); + variantAnnotation.setConsequenceTypes(Arrays.asList(ct, new ConsequenceType())); + Set xrefs = new VariantAnnotationModelUtils().extractXRefs(variantAnnotation); + + assertEquals(7, xrefs.size()); + // Default fields + assertTrue(xrefs.contains("id")); + assertTrue(xrefs.contains("xref1")); + assertTrue(xrefs.contains("GENE")); + + // Untouched hgvs, not starting with ENST or NM_ + assertTrue(xrefs.contains("ENSP00000451720.1:p.Asn134Lys")); + + assertTrue(xrefs.contains("ENST00000680783.1(ENSG00000135744):c.776T>C")); + assertTrue(xrefs.contains("ENST00000680783.1:c.776T>C")); + assertTrue(xrefs.contains("GENE:c.776T>C")); + + } +} \ No newline at end of file diff --git a/opencga-storage/opencga-storage-core/src/test/java/org/opencb/opencga/storage/core/variant/query/executors/VariantQueryExecutorTest.java b/opencga-storage/opencga-storage-core/src/test/java/org/opencb/opencga/storage/core/variant/query/executors/VariantQueryExecutorTest.java index c58328d4469..778257d5999 100644 --- a/opencga-storage/opencga-storage-core/src/test/java/org/opencb/opencga/storage/core/variant/query/executors/VariantQueryExecutorTest.java +++ b/opencga-storage/opencga-storage-core/src/test/java/org/opencb/opencga/storage/core/variant/query/executors/VariantQueryExecutorTest.java @@ -139,6 +139,12 @@ public void testXRefRs() throws StorageEngineException { with("Cosmic", EvidenceEntry::getId, is("COSV60260399")))))); matchers.put("ENST00000341832.11(ENSG00000248333):c.356-1170A>G", hasAnnotation(with("HGVS", VariantAnnotation::getHgvs, hasItem( is("ENST00000341832.11(ENSG00000248333):c.356-1170A>G"))))); + matchers.put("ENST00000341832.11:c.356-1170A>G", hasAnnotation(with("HGVS", VariantAnnotation::getHgvs, hasItem( + // The variant annotation may not have the "alternate" hgvs + is("ENST00000341832.11(ENSG00000248333):c.356-1170A>G"))))); + matchers.put("ENSG00000248333:c.356-1170A>G", hasAnnotation(with("HGVS", VariantAnnotation::getHgvs, hasItem( + // The variant annotation may not have the "alternate" hgvs + is("ENST00000341832.11(ENSG00000248333):c.356-1170A>G"))))); matchers.put("VSP_039324", hasAnnotation( with("ConsequenceType", VariantAnnotation::getConsequenceTypes, hasItem(with("ProteinVariantAnnotation", ConsequenceType::getProteinVariantAnnotation, From d969daff823e1d94ee42422b87b78078a1ee4350 Mon Sep 17 00:00:00 2001 From: imedina Date: Tue, 7 May 2024 17:14:09 +0100 Subject: [PATCH 58/85] storage: Add transcripts starting with 'XM_' to 'isTranscript()', #TASK-6172 --- .../converters/VariantAnnotationModelUtils.java | 10 +++------- .../storage/core/variant/query/VariantQueryUtils.java | 4 ++-- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/annotation/converters/VariantAnnotationModelUtils.java b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/annotation/converters/VariantAnnotationModelUtils.java index b6c8bfcf39d..a4d40cf3d56 100644 --- a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/annotation/converters/VariantAnnotationModelUtils.java +++ b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/annotation/converters/VariantAnnotationModelUtils.java @@ -1,6 +1,7 @@ package org.opencb.opencga.storage.core.variant.annotation.converters; import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.StringUtils; import org.opencb.biodata.models.variant.avro.*; import org.opencb.opencga.storage.core.variant.query.VariantQueryUtils; @@ -81,10 +82,10 @@ public Set extractXRefs(VariantAnnotation variantAnnotation) { for (ConsequenceType conseqType : consequenceTypes) { if (conseqType != null && conseqType.getHgvs() != null && conseqType.getHgvs().contains(hgvs)) { String[] fields = hgvs.split(":", 2); - if (conseqType.getGeneId() != null) { + if (StringUtils.isNotEmpty(conseqType.getGeneId())) { xrefs.add(conseqType.getGeneId() + ":" + fields[1]); } - if (conseqType.getGeneName() != null) { + if (StringUtils.isNotEmpty(conseqType.getGeneName())) { xrefs.add(conseqType.getGeneName() + ":" + fields[1]); } break; @@ -103,11 +104,6 @@ public Set extractXRefs(VariantAnnotation variantAnnotation) { xrefs.add(conseqType.getEnsemblGeneId()); xrefs.add(conseqType.getEnsemblTranscriptId()); - // This is already added in the variantAnnotation.getHgvs() section -// if (conseqType.getHgvs() != null) { -// xrefs.addAll(conseqType.getHgvs()); -// } - ProteinVariantAnnotation protVarAnnotation = conseqType.getProteinVariantAnnotation(); if (protVarAnnotation != null) { xrefs.add(protVarAnnotation.getProteinId()); diff --git a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/VariantQueryUtils.java b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/VariantQueryUtils.java index e57462b5561..9cf773d001f 100644 --- a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/VariantQueryUtils.java +++ b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/VariantQueryUtils.java @@ -470,14 +470,14 @@ public static boolean isVariantAccession(String value) { /** * Determines if the given value might be a known transcript or not. * Ensembl transcripts start with `ENST` - * RefSeq transcripts start with `NM_` + * RefSeq transcripts start with `NM_` and `XM_` * See ... * * @param value Value to check * @return If is a known transcript */ public static boolean isTranscript(String value) { - return value.startsWith("ENST") || value.startsWith("NM_"); + return value.startsWith("ENST") || value.startsWith("NM_") || value.startsWith("XM_"); } /** From 45ca1533e49fbc2a283f3de5bd68510f7576dac5 Mon Sep 17 00:00:00 2001 From: JuanfeSanahuja Date: Tue, 7 May 2024 17:56:56 +0200 Subject: [PATCH 59/85] MailUtils: Refactor ssl and userId variables #TASK-1276 #TASK-464 --- .../auth/authentication/CatalogAuthenticationManager.java | 3 +-- .../java/org/opencb/opencga/core/common/MailUtils.java | 8 +++++--- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/auth/authentication/CatalogAuthenticationManager.java b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/auth/authentication/CatalogAuthenticationManager.java index d86d778a1e2..88b807edd3e 100644 --- a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/auth/authentication/CatalogAuthenticationManager.java +++ b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/auth/authentication/CatalogAuthenticationManager.java @@ -133,8 +133,7 @@ public OpenCGAResult resetPassword(String userId) throws CatalogException { String mailHost = this.emailConfig.getHost(); String mailPort = this.emailConfig.getPort(); try { - MailUtils.sendResetPasswordMail(email, newPassword, mailUser, mailPassword, mailHost, mailPort, - "true", ((User) user.getResults().get(0)).getId()); + MailUtils.sendResetPasswordMail(email, newPassword, mailUser, mailPassword, mailHost, mailPort, userId); result = userDBAdaptor.resetPassword(userId, email, newPassword); } catch (Exception e) { throw new CatalogException("Email could not be sent.", e); diff --git a/opencga-core/src/main/java/org/opencb/opencga/core/common/MailUtils.java b/opencga-core/src/main/java/org/opencb/opencga/core/common/MailUtils.java index ef5852befa8..1802d54a642 100644 --- a/opencga-core/src/main/java/org/opencb/opencga/core/common/MailUtils.java +++ b/opencga-core/src/main/java/org/opencb/opencga/core/common/MailUtils.java @@ -34,14 +34,16 @@ public class MailUtils { private static final Logger logger = LoggerFactory.getLogger(MailUtils.class); + + public static void sendResetPasswordMail(String to, String newPassword, final String mailUser, final String mailPassword, - String mailHost, String mailPort, String ssl, String userId) throws Exception { + String mailHost, String mailPort, String userId) throws Exception { Properties props = new Properties(); - props.put("mail.smtp.auth", "true"); - props.put("mail.smtp.ssl.enable", ssl); props.put("mail.smtp.host", mailHost); props.put("mail.smtp.port", mailPort); + props.put("mail.smtp.auth", "true"); + props.put("mail.smtp.ssl.enable", "true"); props.put("mail.smtp.starttls.enable", "true"); props.put("mail.smtp.starttls.required", "true"); props.put("mail.smtp.ssl.protocols", "TLSv1.2"); From 390f7876000be97af119548838d8a9a064d0e99c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacobo=20Coll=20Morag=C3=B3n?= Date: Wed, 8 May 2024 10:41:35 +0100 Subject: [PATCH 60/85] server: Add server.rest.httpConfiguraiton to configuration.yml #TAKS-8888 --- .../config/AbstractServerConfiguration.java | 13 +- .../opencga/core/config/Configuration.java | 14 +- .../core/config/RestServerConfiguration.java | 122 +++++++++++++++--- .../src/main/resources/configuration.yml | 16 ++- .../core/config/ConfigurationTest.java | 78 ++--------- .../src/test/resources/configuration-test.yml | 2 +- .../opencga/server/AbstractStorageServer.java | 66 +--------- .../org/opencb/opencga/server/RestServer.java | 36 +++++- .../opencga/server/grpc/GrpcServer.java | 19 --- .../main/resources/storage-configuration.yml | 2 - .../server/rest/RestStorageServer.java | 34 ++++- 11 files changed, 209 insertions(+), 193 deletions(-) diff --git a/opencga-core/src/main/java/org/opencb/opencga/core/config/AbstractServerConfiguration.java b/opencga-core/src/main/java/org/opencb/opencga/core/config/AbstractServerConfiguration.java index 060c72ceacc..826fe6998c9 100644 --- a/opencga-core/src/main/java/org/opencb/opencga/core/config/AbstractServerConfiguration.java +++ b/opencga-core/src/main/java/org/opencb/opencga/core/config/AbstractServerConfiguration.java @@ -16,13 +16,13 @@ package org.opencb.opencga.core.config; + /** * Created by imedina on 25/04/16. */ public abstract class AbstractServerConfiguration { protected int port; - protected String logFile; public AbstractServerConfiguration() { } @@ -35,7 +35,6 @@ public AbstractServerConfiguration(int port) { public String toString() { final StringBuilder sb = new StringBuilder("ServerConfiguration{"); sb.append("port=").append(port); - sb.append(", logFile='").append(logFile).append('\''); sb.append('}'); return sb.toString(); } @@ -49,13 +48,9 @@ public AbstractServerConfiguration setPort(int port) { return this; } - public String getLogFile() { - return logFile; - } - - public AbstractServerConfiguration setLogFile(String logFile) { - this.logFile = logFile; - return this; + @Deprecated + protected void setLogFile(Object o) { + Configuration.reportUnusedField("configuration.yml#server.rest.maxLimit", o); } } diff --git a/opencga-core/src/main/java/org/opencb/opencga/core/config/Configuration.java b/opencga-core/src/main/java/org/opencb/opencga/core/config/Configuration.java index bb5057a76e2..fed1d98170b 100644 --- a/opencga-core/src/main/java/org/opencb/opencga/core/config/Configuration.java +++ b/opencga-core/src/main/java/org/opencb/opencga/core/config/Configuration.java @@ -66,6 +66,8 @@ public class Configuration { private static Logger logger; + private static final Set reportedFields = new HashSet<>(); + private static final String DEFAULT_CONFIGURATION_FORMAT = "yaml"; static { @@ -200,6 +202,14 @@ private static void overwriteWithEnvironmentVariables(Configuration configuratio } } + public static void reportUnusedField(String field, Object value) { + if (value != null && !(value instanceof String && ((String) value).isEmpty())) { + if (reportedFields.add(field)) { + logger.warn("Ignored configuration option '{}' with value '{}'. The option was deprecated and removed.", field, value); + } + } + } + @Override public String toString() { final StringBuilder sb = new StringBuilder("Configuration{"); @@ -246,9 +256,7 @@ public String getLogFile() { @Deprecated public Configuration setLogFile(String logFile) { - if (logFile != null) { - logger.warn("Deprecated option 'configuration.yml#logFile'"); - } + reportUnusedField("configuration.yml#logFile", logFile); return this; } diff --git a/opencga-core/src/main/java/org/opencb/opencga/core/config/RestServerConfiguration.java b/opencga-core/src/main/java/org/opencb/opencga/core/config/RestServerConfiguration.java index 99ea3ada10c..f87075e9a02 100644 --- a/opencga-core/src/main/java/org/opencb/opencga/core/config/RestServerConfiguration.java +++ b/opencga-core/src/main/java/org/opencb/opencga/core/config/RestServerConfiguration.java @@ -16,52 +16,132 @@ package org.opencb.opencga.core.config; +import java.util.Objects; + /** * Created by imedina on 22/05/16. */ public class RestServerConfiguration extends AbstractServerConfiguration { - private int defaultLimit; - private int maxLimit; - - + public HttpConfiguration httpConfiguration = new HttpConfiguration(); public RestServerConfiguration() { } public RestServerConfiguration(int port) { - this(port, 2000, 5000); - } - - public RestServerConfiguration(int port, int defaultLimit, int maxLimit) { super(port); - this.defaultLimit = defaultLimit; - this.maxLimit = maxLimit; } @Override public String toString() { final StringBuilder sb = new StringBuilder("RestServerConfiguration{"); - sb.append("defaultLimit=").append(defaultLimit); - sb.append(", maxLimit=").append(maxLimit); + sb.append("port=").append(port); + sb.append(", httpConfiguration=").append(httpConfiguration); sb.append('}'); return sb.toString(); } - public int getDefaultLimit() { - return defaultLimit; + @Deprecated + protected void setDefaultLimit(Object o) { + Configuration.reportUnusedField("configuration.yml#server.rest.defaultLimit", o); } - public RestServerConfiguration setDefaultLimit(int defaultLimit) { - this.defaultLimit = defaultLimit; - return this; + @Deprecated + protected void setMaxLimit(Object o) { + Configuration.reportUnusedField("configuration.yml#server.rest.maxLimit", o); } - public int getMaxLimit() { - return maxLimit; + public HttpConfiguration getHttpConfiguration() { + return httpConfiguration; } - public RestServerConfiguration setMaxLimit(int maxLimit) { - this.maxLimit = maxLimit; + public RestServerConfiguration setHttpConfiguration(HttpConfiguration httpConfiguration) { + this.httpConfiguration = httpConfiguration; return this; } + + public static class HttpConfiguration { + private int outputBufferSize = -1; + private int outputAggregationSize = -1; + private int requestHeaderSize = -1; + private int responseHeaderSize = -1; + private int headerCacheSize = -1; + + public int getOutputBufferSize() { + return outputBufferSize; + } + + public HttpConfiguration setOutputBufferSize(int outputBufferSize) { + this.outputBufferSize = outputBufferSize; + return this; + } + + public int getOutputAggregationSize() { + return outputAggregationSize; + } + + public HttpConfiguration setOutputAggregationSize(int outputAggregationSize) { + this.outputAggregationSize = outputAggregationSize; + return this; + } + + public int getRequestHeaderSize() { + return requestHeaderSize; + } + + public HttpConfiguration setRequestHeaderSize(int requestHeaderSize) { + this.requestHeaderSize = requestHeaderSize; + return this; + } + + public int getResponseHeaderSize() { + return responseHeaderSize; + } + + public HttpConfiguration setResponseHeaderSize(int responseHeaderSize) { + this.responseHeaderSize = responseHeaderSize; + return this; + } + + public int getHeaderCacheSize() { + return headerCacheSize; + } + + public HttpConfiguration setHeaderCacheSize(int headerCacheSize) { + this.headerCacheSize = headerCacheSize; + return this; + } + + @Override + public String toString() { + final StringBuilder sb = new StringBuilder("HttpConfiguration{"); + sb.append("outputBufferSize=").append(outputBufferSize); + sb.append(", outputAggregationSize=").append(outputAggregationSize); + sb.append(", requestHeaderSize=").append(requestHeaderSize); + sb.append(", responseHeaderSize=").append(responseHeaderSize); + sb.append(", headerCacheSize=").append(headerCacheSize); + sb.append('}'); + return sb.toString(); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + HttpConfiguration that = (HttpConfiguration) o; + return outputBufferSize == that.outputBufferSize && + outputAggregationSize == that.outputAggregationSize && + requestHeaderSize == that.requestHeaderSize && + responseHeaderSize == that.responseHeaderSize && + headerCacheSize == that.headerCacheSize; + } + + @Override + public int hashCode() { + return Objects.hash(outputBufferSize, outputAggregationSize, requestHeaderSize, responseHeaderSize, headerCacheSize); + } + } } diff --git a/opencga-core/src/main/resources/configuration.yml b/opencga-core/src/main/resources/configuration.yml index dfc1526ab57..ad99aa68f79 100644 --- a/opencga-core/src/main/resources/configuration.yml +++ b/opencga-core/src/main/resources/configuration.yml @@ -73,12 +73,20 @@ authentication: server: rest: port: ${OPENCGA.SERVER.REST.PORT} - logFile: null - defaultLimit: 2000 - maxLimit: 5000 + httpConfiguration: + # The size in bytes of the output buffer used to aggregate HTTP output + outputBufferSize: 32768 + # The maximum size in bytes for HTTP output to be aggregated + outputAggregationSize: 8192 + # The maximum allowed size in bytes for a HTTP request header + requestHeaderSize: 8192 + # The maximum allowed size in bytes for a HTTP response header + responseHeaderSize: 8192 + # The maximum allowed size in bytes for a HTTP header field cache + headerCacheSize: 4096 + grpc: port: ${OPENCGA.SERVER.GRPC.PORT} - logFile: null optimizations: simplifyPermissions: ${OPENCGA_OPTIMIZATIONS_SIMPLIFY_PERMISSIONS} diff --git a/opencga-core/src/test/java/org/opencb/opencga/core/config/ConfigurationTest.java b/opencga-core/src/test/java/org/opencb/opencga/core/config/ConfigurationTest.java index a617f0049b0..5a65e947bf8 100644 --- a/opencga-core/src/test/java/org/opencb/opencga/core/config/ConfigurationTest.java +++ b/opencga-core/src/test/java/org/opencb/opencga/core/config/ConfigurationTest.java @@ -16,15 +16,15 @@ package org.opencb.opencga.core.config; -import org.apache.commons.lang3.StringUtils; import org.junit.Test; import org.junit.experimental.categories.Category; import org.opencb.opencga.core.testclassification.duration.ShortTests; -import java.io.FileOutputStream; import java.io.IOException; +import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; +import java.text.SimpleDateFormat; import java.util.*; /** @@ -34,68 +34,7 @@ public class ConfigurationTest { @Test - public void test() { - String path1 = "a/b/c.txt"; - String path2 = "a/b/c/"; - String path3 = "p.txt"; - - System.out.println(path1 + " ---- " + getParentPath(path1)); - System.out.println(path2 + " ---- " + getParentPath(path2)); - System.out.println(path3 + " ---- " + getParentPath(path3)); - - System.out.println(path1 + " ---- " + calculateAllPossiblePaths(path1)); - System.out.println(path2 + " ---- " + calculateAllPossiblePaths(path2)); - System.out.println(path3 + " ---- " + calculateAllPossiblePaths(path3)); - System.out.println("'' ---- " + calculateAllPossiblePaths("")); - - System.out.println(path1 + " ---- " + getFileName(path1)); - System.out.println(path2 + " ---- " + getFileName(path2)); - System.out.println(path3 + " ---- " + getFileName(path3)); - System.out.println("'' ---- " + getFileName("")); - - } - - String getParentPath(String strPath) { - Path path = Paths.get(strPath); - Path parent = path.getParent(); - if (parent != null) { - return parent.toString() + "/"; - } else { - return ""; - } - } - - String getFileName(String strPath) { - if (StringUtils.isEmpty(strPath)) { - return "."; - } - return Paths.get(strPath).getFileName().toString(); - } - - public static List calculateAllPossiblePaths(String filePath) { - if (StringUtils.isEmpty(filePath) || "/".equals(filePath)) { - return Collections.singletonList(""); - } - StringBuilder pathBuilder = new StringBuilder(); - String[] split = filePath.split("/"); - List paths = new ArrayList<>(split.length + 1); - paths.add(""); //Add study root folder - //Add intermediate folders - //Do not add the last split, could be a file or a folder.. - //Depending on this, it could end with '/' or not. - for (int i = 0; i < split.length - 1; i++) { - String f = split[i]; - System.out.println(f); - pathBuilder = new StringBuilder(pathBuilder.toString()).append(f).append("/"); - paths.add(pathBuilder.toString()); - } - paths.add(filePath); //Add the file path - return paths; - } - - - @Test - public void testDefault() { + public void testDefault() throws IOException { Configuration configuration = new Configuration(); configuration.setLogLevel("INFO"); @@ -136,7 +75,7 @@ public void testDefault() { configuration.setAudit(audit); ServerConfiguration serverConfiguration = new ServerConfiguration(); - RestServerConfiguration rest = new RestServerConfiguration(1000, 100, 1000); + RestServerConfiguration rest = new RestServerConfiguration(1000); GrpcServerConfiguration grpc = new GrpcServerConfiguration(1001); serverConfiguration.setGrpc(grpc); serverConfiguration.setRest(rest); @@ -155,11 +94,10 @@ public void testDefault() { // catalogConfiguration.getStorageEngines().add(storageEngineConfiguration1); // catalogConfiguration.getStorageEngines().add(storageEngineConfiguration2); - try { - configuration.serialize(new FileOutputStream("/tmp/configuration-test.yml")); - } catch (IOException e) { - e.printStackTrace(); - } + Path outdir = Paths.get("target/test-data", "junit-opencga-" + + new SimpleDateFormat("yyyy-MM-dd_HH-mm-ss.SSS").format(new Date())); + Files.createDirectories(outdir); + configuration.serialize(Files.newOutputStream(outdir.resolve("configuration-test.yml").toFile().toPath())); } @Test diff --git a/opencga-core/src/test/resources/configuration-test.yml b/opencga-core/src/test/resources/configuration-test.yml index 4d8d3c10f25..dad67f8c5dc 100644 --- a/opencga-core/src/test/resources/configuration-test.yml +++ b/opencga-core/src/test/resources/configuration-test.yml @@ -46,7 +46,7 @@ authentication: server: rest: port: 8080 - logFile: null + logFile: "some_file_but_this_field_is_deprecated" defaultLimit: 2000 maxLimit: 5000 diff --git a/opencga-server/src/main/java/org/opencb/opencga/server/AbstractStorageServer.java b/opencga-server/src/main/java/org/opencb/opencga/server/AbstractStorageServer.java index e1e880f2d47..d4bcb75d575 100644 --- a/opencga-server/src/main/java/org/opencb/opencga/server/AbstractStorageServer.java +++ b/opencga-server/src/main/java/org/opencb/opencga/server/AbstractStorageServer.java @@ -16,58 +16,29 @@ package org.opencb.opencga.server; -import org.apache.commons.lang3.StringUtils; import org.opencb.opencga.core.config.Configuration; import org.opencb.opencga.core.config.storage.StorageConfiguration; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.io.File; -import java.io.FileInputStream; import java.io.IOException; +import java.io.UncheckedIOException; import java.nio.file.Files; import java.nio.file.Path; -import java.nio.file.Paths; /** * Created by imedina on 02/01/16. */ public abstract class AbstractStorageServer { - @Deprecated - protected Path configDir; protected Path opencgaHome; protected int port; protected Configuration configuration; protected StorageConfiguration storageConfiguration; - /** - * This is the default StorageEngine to use when it is not provided by the client. - */ - @Deprecated - protected String defaultStorageEngine; - protected Logger logger; - - @Deprecated - public AbstractStorageServer() { - initDefaultConfigurationFiles(); - } - - @Deprecated - public AbstractStorageServer(int port, String defaultStorageEngine) { - initDefaultConfigurationFiles(); - - this.port = port; - if (StringUtils.isNotEmpty(defaultStorageEngine)) { - this.defaultStorageEngine = defaultStorageEngine; - } else { - this.defaultStorageEngine = storageConfiguration.getVariant().getDefaultEngine(); - } - } - public AbstractStorageServer(Path opencgaHome) { this(opencgaHome, 0); } @@ -93,33 +64,15 @@ private void initConfigurationFiles(Path opencgaHome) { try { if (opencgaHome != null && Files.exists(opencgaHome) && Files.isDirectory(opencgaHome) && Files.exists(opencgaHome.resolve("conf"))) { - logger.info("Loading configuration files from '{}'", opencgaHome.toString()); -// generalConfiguration = GeneralConfiguration.load(GeneralConfiguration.class.getClassLoader().getResourceAsStream("configuration.yml")); - configuration = Configuration - .load(new FileInputStream(new File(opencgaHome.resolve("conf").toFile().getAbsolutePath() + "/configuration.yml"))); - storageConfiguration = StorageConfiguration - .load(new FileInputStream(new File(opencgaHome.resolve("conf").toFile().getAbsolutePath() + "/storage-configuration.yml"))); - } - } catch (IOException e) { - e.printStackTrace(); - } - } - - @Deprecated - private void initDefaultConfigurationFiles() { - try { - if (System.getenv("OPENCGA_HOME") != null) { - initConfigurationFiles(Paths.get(System.getenv("OPENCGA_HOME") + "/conf")); - } else { - logger.info("Loading configuration files from inside JAR file"); + logger.info("Loading configuration files from '{}'", opencgaHome); // generalConfiguration = GeneralConfiguration.load(GeneralConfiguration.class.getClassLoader().getResourceAsStream("configuration.yml")); configuration = Configuration - .load(Configuration.class.getClassLoader().getResourceAsStream("configuration.yml")); + .load(Files.newInputStream(opencgaHome.resolve("conf").resolve("configuration.yml").toFile().toPath())); storageConfiguration = StorageConfiguration - .load(StorageConfiguration.class.getClassLoader().getResourceAsStream("storage-configuration.yml")); + .load(Files.newInputStream(opencgaHome.resolve("conf").resolve("storage-configuration.yml").toFile().toPath())); } } catch (IOException e) { - e.printStackTrace(); + throw new UncheckedIOException(e); } } @@ -133,7 +86,6 @@ private void initDefaultConfigurationFiles() { public String toString() { final StringBuilder sb = new StringBuilder("StorageServer{"); sb.append("port=").append(port); - sb.append(", defaultStorageEngine='").append(defaultStorageEngine).append('\''); sb.append('}'); return sb.toString(); } @@ -146,12 +98,4 @@ public void setPort(int port) { this.port = port; } - public String getDefaultStorageEngine() { - return defaultStorageEngine; - } - - public void setDefaultStorageEngine(String defaultStorageEngine) { - this.defaultStorageEngine = defaultStorageEngine; - } - } diff --git a/opencga-server/src/main/java/org/opencb/opencga/server/RestServer.java b/opencga-server/src/main/java/org/opencb/opencga/server/RestServer.java index 28bdffc8016..1e991053645 100644 --- a/opencga-server/src/main/java/org/opencb/opencga/server/RestServer.java +++ b/opencga-server/src/main/java/org/opencb/opencga/server/RestServer.java @@ -16,8 +16,12 @@ package org.opencb.opencga.server; +import org.eclipse.jetty.server.HttpConfiguration; +import org.eclipse.jetty.server.HttpConnectionFactory; import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.server.ServerConnector; import org.eclipse.jetty.webapp.WebAppContext; +import org.opencb.opencga.core.config.RestServerConfiguration; import java.io.IOException; import java.nio.file.Files; @@ -44,7 +48,14 @@ public RestServer(Path opencgaHome, int port) { @Override public void start() throws Exception { - server = new Server(port); + server = new Server(); + + HttpConfiguration httpConfig = getHttpConfiguration(); + + ServerConnector httpConnector = new ServerConnector(server, new HttpConnectionFactory(httpConfig)); + httpConnector.setPort(port); + + server.addConnector(httpConnector); WebAppContext webapp = new WebAppContext(); Optional warPath; @@ -56,7 +67,7 @@ public void start() throws Exception { throw new Exception("Error accessing OpenCGA Home: " + opencgaHome.toString(), e); } // Check is a war file has been found in opencgaHome - if (warPath == null || !warPath.isPresent()) { + if (!warPath.isPresent()) { throw new Exception("No war file found at " + opencgaHome.toString()); } @@ -105,6 +116,27 @@ public void run() { // AdminRestWebService.setServer(this); } + private HttpConfiguration getHttpConfiguration() { + HttpConfiguration httpConfig = new HttpConfiguration(); + RestServerConfiguration.HttpConfiguration restHttpConf = configuration.getServer().getRest().getHttpConfiguration(); + if (restHttpConf.getOutputBufferSize() > 0) { + httpConfig.setOutputBufferSize(restHttpConf.getOutputBufferSize()); + } + if (restHttpConf.getOutputAggregationSize() > 0) { + httpConfig.setOutputAggregationSize(restHttpConf.getOutputAggregationSize()); + } + if (restHttpConf.getRequestHeaderSize() > 0) { + httpConfig.setRequestHeaderSize(restHttpConf.getRequestHeaderSize()); + } + if (restHttpConf.getResponseHeaderSize() > 0) { + httpConfig.setResponseHeaderSize(restHttpConf.getResponseHeaderSize()); + } + if (restHttpConf.getHeaderCacheSize() > 0) { + httpConfig.setHeaderCacheSize(restHttpConf.getHeaderCacheSize()); + } + return httpConfig; + } + @Override public void stop() throws Exception { // By setting exit to true the monitor thread will close the Jetty server diff --git a/opencga-server/src/main/java/org/opencb/opencga/server/grpc/GrpcServer.java b/opencga-server/src/main/java/org/opencb/opencga/server/grpc/GrpcServer.java index 76b4c350a32..32ded068042 100644 --- a/opencga-server/src/main/java/org/opencb/opencga/server/grpc/GrpcServer.java +++ b/opencga-server/src/main/java/org/opencb/opencga/server/grpc/GrpcServer.java @@ -19,7 +19,6 @@ import io.grpc.Server; import io.grpc.ServerBuilder; import org.opencb.opencga.server.AbstractStorageServer; -import org.opencb.opencga.core.config.storage.StorageConfiguration; import org.slf4j.LoggerFactory; import java.nio.file.Path; @@ -31,29 +30,11 @@ public class GrpcServer extends AbstractStorageServer { private Server server; - public GrpcServer() { -// this(storageConfiguration.getServer().getGrpc(), storageConfiguration.getDefaultStorageEngineId()); - } - - public GrpcServer(int port, String defaultStorageEngine) { - super(port, defaultStorageEngine); - - logger = LoggerFactory.getLogger(this.getClass()); - } - public GrpcServer(Path configDir) { super(configDir); init(); } - @Deprecated - public GrpcServer(StorageConfiguration storageConfiguration) { -// super(storageConfiguration.getServer().getGrpc(), storageConfiguration.getDefaultStorageEngineId()); - this.storageConfiguration = storageConfiguration; - - logger = LoggerFactory.getLogger(this.getClass()); - } - private void init() { logger = LoggerFactory.getLogger(this.getClass()); if (configuration != null) { diff --git a/opencga-storage/opencga-storage-core/src/main/resources/storage-configuration.yml b/opencga-storage/opencga-storage-core/src/main/resources/storage-configuration.yml index 226fc106783..4f64a3ad939 100644 --- a/opencga-storage/opencga-storage-core/src/main/resources/storage-configuration.yml +++ b/opencga-storage/opencga-storage-core/src/main/resources/storage-configuration.yml @@ -18,10 +18,8 @@ cellbase: server: rest: port: ${OPENCGA.SERVER.REST.PORT} - logFile: null grpc: port: ${OPENCGA.SERVER.GRPC.PORT} - logFile: null ## Solr Search Configuration search: diff --git a/opencga-storage/opencga-storage-server/src/main/java/org/opencb/opencga/storage/server/rest/RestStorageServer.java b/opencga-storage/opencga-storage-server/src/main/java/org/opencb/opencga/storage/server/rest/RestStorageServer.java index 226c8ab46ce..5343a17eb1d 100644 --- a/opencga-storage/opencga-storage-server/src/main/java/org/opencb/opencga/storage/server/rest/RestStorageServer.java +++ b/opencga-storage/opencga-storage-server/src/main/java/org/opencb/opencga/storage/server/rest/RestStorageServer.java @@ -16,11 +16,15 @@ package org.opencb.opencga.storage.server.rest; +import org.eclipse.jetty.server.HttpConfiguration; +import org.eclipse.jetty.server.HttpConnectionFactory; import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.server.ServerConnector; import org.eclipse.jetty.servlet.ServletContextHandler; import org.eclipse.jetty.servlet.ServletHolder; import org.glassfish.jersey.server.ResourceConfig; import org.glassfish.jersey.servlet.ServletContainer; +import org.opencb.opencga.core.config.RestServerConfiguration; import org.opencb.opencga.core.config.storage.StorageConfiguration; import org.opencb.opencga.storage.server.common.AbstractStorageServer; import org.slf4j.LoggerFactory; @@ -60,7 +64,14 @@ public void start() throws Exception { ServletHolder sh = new ServletHolder("opencga", sc); logger.info("Server in port : {}", port); - server = new Server(port); + server = new Server(); + + HttpConfiguration httpConfig = getHttpConfiguration(); + + ServerConnector httpConnector = new ServerConnector(server, new HttpConnectionFactory(httpConfig)); + httpConnector.setPort(port); + + server.addConnector(httpConnector); ServletContextHandler context = new ServletContextHandler(server, null, ServletContextHandler.SESSIONS); context.addServlet(sh, "/opencga/webservices/rest/*"); @@ -103,6 +114,27 @@ public void run() { AdminRestWebService.setServer(this); } + private HttpConfiguration getHttpConfiguration() { + HttpConfiguration httpConfig = new HttpConfiguration(); + RestServerConfiguration.HttpConfiguration restHttpConf = storageConfiguration.getServer().getRest().getHttpConfiguration(); + if (restHttpConf.getOutputBufferSize() > 0) { + httpConfig.setOutputBufferSize(restHttpConf.getOutputBufferSize()); + } + if (restHttpConf.getOutputAggregationSize() > 0) { + httpConfig.setOutputAggregationSize(restHttpConf.getOutputAggregationSize()); + } + if (restHttpConf.getRequestHeaderSize() > 0) { + httpConfig.setRequestHeaderSize(restHttpConf.getRequestHeaderSize()); + } + if (restHttpConf.getResponseHeaderSize() > 0) { + httpConfig.setResponseHeaderSize(restHttpConf.getResponseHeaderSize()); + } + if (restHttpConf.getHeaderCacheSize() > 0) { + httpConfig.setHeaderCacheSize(restHttpConf.getHeaderCacheSize()); + } + return httpConfig; + } + @Override public void stop() throws Exception { // By setting exit to true the monitor thread will close the Jetty server From f661aeba17975b13e77603da3ac69ca11df4e855 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacobo=20Coll=20Morag=C3=B3n?= Date: Wed, 8 May 2024 12:18:26 +0100 Subject: [PATCH 61/85] server: Extract individual init methods at RestServer #TASK-5888 --- .../org/opencb/opencga/server/RestServer.java | 58 ++++++++++++------- 1 file changed, 37 insertions(+), 21 deletions(-) diff --git a/opencga-server/src/main/java/org/opencb/opencga/server/RestServer.java b/opencga-server/src/main/java/org/opencb/opencga/server/RestServer.java index 1e991053645..c3f87c68239 100644 --- a/opencga-server/src/main/java/org/opencb/opencga/server/RestServer.java +++ b/opencga-server/src/main/java/org/opencb/opencga/server/RestServer.java @@ -48,6 +48,22 @@ public RestServer(Path opencgaHome, int port) { @Override public void start() throws Exception { + initServer(); + + Path war = getOpencgaWar(); + + initWebApp(war); + + server.start(); + logger.info("REST server started, listening on {}", server.getURI()); + + initHooks(); + +// // AdminWSServer server needs a reference to this class to cll to .stop() +// AdminRestWebService.setServer(this); + } + + protected Server initServer() { server = new Server(); HttpConfiguration httpConfig = getHttpConfiguration(); @@ -56,8 +72,10 @@ public void start() throws Exception { httpConnector.setPort(port); server.addConnector(httpConnector); + return server; + } - WebAppContext webapp = new WebAppContext(); + protected Path getOpencgaWar() throws Exception { Optional warPath; try (Stream stream = Files.list(opencgaHome)) { warPath = stream @@ -70,32 +88,33 @@ public void start() throws Exception { if (!warPath.isPresent()) { throw new Exception("No war file found at " + opencgaHome.toString()); } + return warPath.get(); + } - String opencgaVersion = warPath.get().toFile().getName().replace(".war", ""); + protected WebAppContext initWebApp(Path war) throws Exception { + String opencgaVersion = war.toFile().getName().replace(".war", ""); + WebAppContext webapp = new WebAppContext(); webapp.setContextPath("/" + opencgaVersion); - webapp.setWar(warPath.get().toString()); + webapp.setWar(war.toString()); webapp.setClassLoader(this.getClass().getClassLoader()); webapp.setInitParameter("OPENCGA_HOME", opencgaHome.toFile().toString()); webapp.getServletContext().setAttribute("OPENCGA_HOME", opencgaHome.toFile().toString()); // webapp.setInitParameter("log4jConfiguration", opencgaHome.resolve("conf/log4j2.server.xml").toString()); server.setHandler(webapp); + return webapp; + } - server.start(); - logger.info("REST server started, listening on {}", port); - + protected void initHooks() { // A hook is added in case the JVM is shutting down - Runtime.getRuntime().addShutdownHook(new Thread() { - @Override - public void run() { - try { - if (server.isRunning()) { - stopJettyServer(); - } - } catch (Exception e) { - e.printStackTrace(); + Runtime.getRuntime().addShutdownHook(new Thread(() -> { + try { + if (server.isRunning()) { + stopJettyServer(); } + } catch (Exception e) { + logger.error("Error stopping Jetty server", e); } - }); + })); // A separated thread is launched to shut down the server new Thread(() -> { @@ -108,15 +127,12 @@ public void run() { Thread.sleep(500); } } catch (Exception e) { - e.printStackTrace(); + logger.error("Error stopping Jetty server", e); } }).start(); - -// // AdminWSServer server needs a reference to this class to cll to .stop() -// AdminRestWebService.setServer(this); } - private HttpConfiguration getHttpConfiguration() { + protected HttpConfiguration getHttpConfiguration() { HttpConfiguration httpConfig = new HttpConfiguration(); RestServerConfiguration.HttpConfiguration restHttpConf = configuration.getServer().getRest().getHttpConfiguration(); if (restHttpConf.getOutputBufferSize() > 0) { From 9aae8c1650cf034c0905c69ff9cd61e679cef247 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacobo=20Coll=20Morag=C3=B3n?= Date: Wed, 8 May 2024 12:28:53 +0100 Subject: [PATCH 62/85] core: Fix typo on unused configuration field. #TASK-5888 --- .../opencb/opencga/core/config/AbstractServerConfiguration.java | 2 +- .../main/java/org/opencb/opencga/core/config/Configuration.java | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/opencga-core/src/main/java/org/opencb/opencga/core/config/AbstractServerConfiguration.java b/opencga-core/src/main/java/org/opencb/opencga/core/config/AbstractServerConfiguration.java index 826fe6998c9..cffc7fe68b8 100644 --- a/opencga-core/src/main/java/org/opencb/opencga/core/config/AbstractServerConfiguration.java +++ b/opencga-core/src/main/java/org/opencb/opencga/core/config/AbstractServerConfiguration.java @@ -50,7 +50,7 @@ public AbstractServerConfiguration setPort(int port) { @Deprecated protected void setLogFile(Object o) { - Configuration.reportUnusedField("configuration.yml#server.rest.maxLimit", o); + Configuration.reportUnusedField("configuration.yml#server.[rest|grpc].logFile", o); } } diff --git a/opencga-core/src/main/java/org/opencb/opencga/core/config/Configuration.java b/opencga-core/src/main/java/org/opencb/opencga/core/config/Configuration.java index fed1d98170b..be957b160a7 100644 --- a/opencga-core/src/main/java/org/opencb/opencga/core/config/Configuration.java +++ b/opencga-core/src/main/java/org/opencb/opencga/core/config/Configuration.java @@ -203,8 +203,10 @@ private static void overwriteWithEnvironmentVariables(Configuration configuratio } public static void reportUnusedField(String field, Object value) { + // Report only if the value is not null and not an empty string if (value != null && !(value instanceof String && ((String) value).isEmpty())) { if (reportedFields.add(field)) { + // Only log the first time a field is found logger.warn("Ignored configuration option '{}' with value '{}'. The option was deprecated and removed.", field, value); } } From faffa3f47486996c8cc30ded81baf21a70ead59b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacobo=20Coll=20Morag=C3=B3n?= Date: Wed, 8 May 2024 16:39:15 +0100 Subject: [PATCH 63/85] storage: Include variant stats currently being updated in variant results. #TASK-6201 --- .../core/cellbase/CellBaseValidator.java | 19 ++++- .../VariantStorageMetadataManager.java | 9 ++- .../VariantQueryProjectionParser.java | 10 ++- .../DefaultVariantStatisticsManager.java | 1 + .../stats/VariantStatisticsManager.java | 1 + .../stats/VariantStatisticsManagerTest.java | 74 +++++++++++++++---- .../phoenix/VariantPhoenixSchemaManager.java | 2 +- ...condaryIndexPendingVariantsDescriptor.java | 2 +- 8 files changed, 96 insertions(+), 22 deletions(-) diff --git a/opencga-core/src/main/java/org/opencb/opencga/core/cellbase/CellBaseValidator.java b/opencga-core/src/main/java/org/opencb/opencga/core/cellbase/CellBaseValidator.java index 6d7eafd1503..5ed331143db 100644 --- a/opencga-core/src/main/java/org/opencb/opencga/core/cellbase/CellBaseValidator.java +++ b/opencga-core/src/main/java/org/opencb/opencga/core/cellbase/CellBaseValidator.java @@ -9,6 +9,7 @@ import org.opencb.cellbase.core.config.SpeciesProperties; import org.opencb.cellbase.core.models.DataRelease; import org.opencb.cellbase.core.result.CellBaseDataResponse; +import org.opencb.commons.datastore.core.ObjectMap; import org.opencb.commons.datastore.core.QueryOptions; import org.opencb.commons.utils.VersionUtils; @@ -307,9 +308,13 @@ private static String majorMinor(String version) { public String getVersionFromServer() throws IOException { if (serverVersion == null) { synchronized (this) { - String serverVersion = cellBaseClient.getMetaClient().about().firstResult().getString("Version"); + ObjectMap result = retryMetaAbout(3); + if (result == null) { + throw new IOException("Unable to get version from server for cellbase " + toString()); + } + String serverVersion = result.getString("Version"); if (StringUtils.isEmpty(serverVersion)) { - serverVersion = cellBaseClient.getMetaClient().about().firstResult().getString("Version: "); + serverVersion = result.getString("Version: "); } this.serverVersion = serverVersion; } @@ -317,6 +322,16 @@ public String getVersionFromServer() throws IOException { return serverVersion; } + private ObjectMap retryMetaAbout(int retries) throws IOException { + ObjectMap result = cellBaseClient.getMetaClient().about().firstResult(); + if (result == null && retries > 0) { + // Retry + logger.warn("Unable to get version from server for cellbase " + toString() + ". Retrying..."); + result = retryMetaAbout(retries - 1); + } + return result; + } + public boolean isMinVersion(String minVersion) throws IOException { String serverVersion = getVersionFromServer(); return VersionUtils.isMinVersion(minVersion, serverVersion); diff --git a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/metadata/VariantStorageMetadataManager.java b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/metadata/VariantStorageMetadataManager.java index 65812bd7017..46872f47103 100644 --- a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/metadata/VariantStorageMetadataManager.java +++ b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/metadata/VariantStorageMetadataManager.java @@ -1135,9 +1135,14 @@ public Iterable getInvalidCohorts(int studyId) { return () -> Iterators.filter(cohortIterator(studyId), CohortMetadata::isInvalid); } - public Iterable getCalculatedOrInvalidCohorts(int studyId) { + public Iterable getCalculatedOrPartialCohorts(int studyId) { return () -> Iterators.filter(cohortIterator(studyId), - cohortMetadata -> cohortMetadata.isStatsReady() || cohortMetadata.isInvalid()); + cohortMetadata -> { + TaskMetadata.Status status = cohortMetadata.getStatsStatus(); + return status == TaskMetadata.Status.READY + || status == TaskMetadata.Status.RUNNING + || status == TaskMetadata.Status.ERROR; + }); } public CohortMetadata setSamplesToCohort(int studyId, String cohortName, Collection samples) throws StorageEngineException { diff --git a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/projection/VariantQueryProjectionParser.java b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/projection/VariantQueryProjectionParser.java index 3ec0c32c08a..bdcd501ad88 100644 --- a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/projection/VariantQueryProjectionParser.java +++ b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/query/projection/VariantQueryProjectionParser.java @@ -8,6 +8,7 @@ import org.opencb.opencga.storage.core.metadata.models.CohortMetadata; import org.opencb.opencga.storage.core.metadata.models.FileMetadata; import org.opencb.opencga.storage.core.metadata.models.StudyMetadata; +import org.opencb.opencga.storage.core.metadata.models.TaskMetadata; import org.opencb.opencga.storage.core.variant.VariantStorageEngine; import org.opencb.opencga.storage.core.variant.adaptors.VariantField; import org.opencb.opencga.storage.core.variant.adaptors.VariantQueryException; @@ -134,9 +135,10 @@ public VariantQueryProjection parseVariantQueryProjection(Query query, QueryOpti for (VariantQueryProjection.StudyVariantQueryProjection study : studies.values()) { int studyId = study.getId(); List cohorts = new LinkedList<>(); - for (CohortMetadata cohort : metadataManager.getCalculatedOrInvalidCohorts(studyId)) { + for (CohortMetadata cohort : metadataManager.getCalculatedOrPartialCohorts(studyId)) { cohorts.add(cohort.getId()); - if (cohort.isInvalid()) { + TaskMetadata.Status status = cohort.getStatsStatus(); + if (status == TaskMetadata.Status.ERROR) { String message = "Please note that the Cohort Stats for " + "'" + study.getName() + ":" + cohort.getName() + "' are currently outdated."; int numSampmles = cohort.getSamples().size(); @@ -147,6 +149,10 @@ public VariantQueryProjection parseVariantQueryProjection(Query query, QueryOpti } message += " To display updated statistics, please execute variant-stats-index."; events.add(new Event(Event.Type.WARNING, message)); + } else if (status == TaskMetadata.Status.RUNNING) { + String message = "Please note that the Cohort Stats for " + + "'" + study.getName() + ":" + cohort.getName() + "' are currently being calculated."; + events.add(new Event(Event.Type.WARNING, message)); } } study.setCohorts(cohorts); diff --git a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/stats/DefaultVariantStatisticsManager.java b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/stats/DefaultVariantStatisticsManager.java index c85c63b1505..db6ead71f58 100644 --- a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/stats/DefaultVariantStatisticsManager.java +++ b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/stats/DefaultVariantStatisticsManager.java @@ -474,6 +474,7 @@ protected VariantStatsDBWriter newVariantStatisticsDBWriter(VariantDBAdaptor dbA // // } + @Deprecated void checkAndUpdateCalculatedCohorts(StudyMetadata studyMetadata, URI uri, boolean updateStats) throws IOException, StorageEngineException { Set cohortNames = readCohortsFromStatsFile(uri); diff --git a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/stats/VariantStatisticsManager.java b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/stats/VariantStatisticsManager.java index fe6765529fa..d4fdc948622 100644 --- a/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/stats/VariantStatisticsManager.java +++ b/opencga-storage/opencga-storage-core/src/main/java/org/opencb/opencga/storage/core/variant/stats/VariantStatisticsManager.java @@ -112,6 +112,7 @@ public void postCalculateStats( } } + @Deprecated public static void checkAndUpdateCalculatedCohorts( VariantStorageMetadataManager metadataManager, StudyMetadata studyMetadata, Collection cohorts, boolean updateStats) throws StorageEngineException { diff --git a/opencga-storage/opencga-storage-core/src/test/java/org/opencb/opencga/storage/core/variant/stats/VariantStatisticsManagerTest.java b/opencga-storage/opencga-storage-core/src/test/java/org/opencb/opencga/storage/core/variant/stats/VariantStatisticsManagerTest.java index baafe7d0ad6..e90b49cff4d 100644 --- a/opencga-storage/opencga-storage-core/src/test/java/org/opencb/opencga/storage/core/variant/stats/VariantStatisticsManagerTest.java +++ b/opencga-storage/opencga-storage-core/src/test/java/org/opencb/opencga/storage/core/variant/stats/VariantStatisticsManagerTest.java @@ -18,6 +18,7 @@ import org.junit.*; import org.junit.rules.ExpectedException; +import org.mockito.Mockito; import org.opencb.biodata.models.variant.Genotype; import org.opencb.biodata.models.variant.StudyEntry; import org.opencb.biodata.models.variant.Variant; @@ -33,7 +34,9 @@ import org.opencb.opencga.storage.core.metadata.models.CohortMetadata; import org.opencb.opencga.storage.core.metadata.models.SampleMetadata; import org.opencb.opencga.storage.core.metadata.models.StudyMetadata; +import org.opencb.opencga.storage.core.metadata.models.TaskMetadata; import org.opencb.opencga.storage.core.variant.VariantStorageBaseTest; +import org.opencb.opencga.storage.core.variant.VariantStorageEngine; import org.opencb.opencga.storage.core.variant.VariantStorageEngineTest; import org.opencb.opencga.storage.core.variant.VariantStorageOptions; import org.opencb.opencga.storage.core.variant.adaptors.VariantDBAdaptor; @@ -49,8 +52,7 @@ import java.util.*; import java.util.stream.Collectors; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; +import static org.junit.Assert.*; /** * Created by hpccoll1 on 01/06/15. @@ -123,32 +125,76 @@ public void queryInvalidStats() throws Exception { Iterator iterator = metadataManager.sampleMetadataIterator(studyMetadata.getId()); /** Create cohorts **/ - HashSet cohort1 = new HashSet<>(); - cohort1.add(iterator.next().getName()); - cohort1.add(iterator.next().getName()); + HashSet cohort1Samples = new HashSet<>(); + cohort1Samples.add(iterator.next().getName()); + cohort1Samples.add(iterator.next().getName()); - HashSet cohort2 = new HashSet<>(); - cohort2.add(iterator.next().getName()); - cohort2.add(iterator.next().getName()); + HashSet cohort2Samples = new HashSet<>(); + cohort2Samples.add(iterator.next().getName()); + cohort2Samples.add(iterator.next().getName()); Map> cohorts = new HashMap<>(); - cohorts.put("cohort1", cohort1); - cohorts.put("cohort2", cohort2); + cohorts.put("cohort1", cohort1Samples); + cohorts.put("cohort2", cohort2Samples); + + // Just cohort ALL is expected + VariantQueryResult result = variantStorageEngine.get(new Query(), new QueryOptions(QueryOptions.LIMIT, 1)); + assertEquals(1, result.first().getStudies().get(0).getStats().size()); + assertEquals(0, result.getEvents().size()); + + metadataManager.registerCohort(studyMetadata.getName(), "cohort1", cohort1Samples); + + // Still just cohort ALL is expected, as cohort1 is not ready nor partial + result = variantStorageEngine.get(new Query(), new QueryOptions(QueryOptions.LIMIT, 1)); + assertEquals(1, result.first().getStudies().get(0).getStats().size()); + assertEquals(0, result.getEvents().size()); //Calculate stats stats(options, studyMetadata.getName(), cohorts, outputUri.resolve("cohort1.cohort2.stats")); checkCohorts(dbAdaptor, studyMetadata); - List cohort1Samples = metadataManager.getCohortMetadata(studyMetadata.getId(), "cohort1").getSamples(); - CohortMetadata cohort = metadataManager.addSamplesToCohort(studyMetadata.getId(), "cohort2", cohort1Samples); - assertTrue(cohort.isInvalid()); + // All 3 cohorts are ready and expected + result = variantStorageEngine.get(new Query(), new QueryOptions(QueryOptions.LIMIT, 1)); + assertEquals(3, result.first().getStudies().get(0).getStats().size()); + assertEquals(0, result.getEvents().size()); - VariantQueryResult result = variantStorageEngine.get(new Query(), new QueryOptions(QueryOptions.LIMIT, 1)); + List cohort1SampleIds = metadataManager.getCohortMetadata(studyMetadata.getId(), "cohort1").getSamples(); + CohortMetadata cohort2 = metadataManager.addSamplesToCohort(studyMetadata.getId(), "cohort2", cohort1SampleIds); + assertTrue(cohort2.isInvalid()); + + // Cohort2 is invalid, but still all cohorts are expected, but with a warning event + result = variantStorageEngine.get(new Query(), new QueryOptions(QueryOptions.LIMIT, 1)); + assertEquals(3, result.first().getStudies().get(0).getStats().size()); assertEquals(1, result.getEvents().size()); assertEquals("Please note that the Cohort Stats for '1000g:cohort2' are currently outdated." + " The statistics have been calculated with 2 samples, while the total number of samples in the cohort is 4." + " To display updated statistics, please execute variant-stats-index.", result.getEvents().get(0).getMessage()); + + VariantStorageEngine engineMock = Mockito.spy(variantStorageEngine); + VariantStatisticsManager statsManagerMock = Mockito.spy(variantStorageEngine.newVariantStatisticsManager()); + Mockito.doReturn(statsManagerMock).when(engineMock).newVariantStatisticsManager(); + Mockito.doAnswer(invocation -> { + invocation.callRealMethod(); + throw new StorageEngineException("Mock error calculating stats"); + }).when(statsManagerMock).preCalculateStats(Mockito.any(), Mockito.any(), Mockito.anyList(), Mockito.anyBoolean(), Mockito.any()); + + options.put(DefaultVariantStatisticsManager.OUTPUT, outputUri.resolve("stats_mock_fail").toString()); + try { + engineMock.calculateStats(studyMetadata.getName(), Collections.singletonList(cohort2.getName()), options); + fail("Expected to fail mock"); + } catch (Exception e) { + assertEquals("Mock error calculating stats", e.getMessage()); + } + + cohort2 = metadataManager.getCohortMetadata(studyMetadata.getId(), cohort2.getName()); + assertEquals(TaskMetadata.Status.RUNNING, cohort2.getStatsStatus()); + + result = variantStorageEngine.get(new Query(), new QueryOptions(QueryOptions.LIMIT, 1)); + assertEquals(3, result.first().getStudies().get(0).getStats().size()); + assertEquals(1, result.getEvents().size()); + assertEquals("Please note that the Cohort Stats for '1000g:cohort2' are currently being calculated.", + result.getEvents().get(0).getMessage()); } @Test diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/adaptors/phoenix/VariantPhoenixSchemaManager.java b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/adaptors/phoenix/VariantPhoenixSchemaManager.java index 4ffa3c7aa55..6f917dbabdd 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/adaptors/phoenix/VariantPhoenixSchemaManager.java +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/adaptors/phoenix/VariantPhoenixSchemaManager.java @@ -79,7 +79,7 @@ public void registerStudyColumns(int studyId) throws StorageEngineException { registerNewFiles(studyId, new ArrayList<>(metadataManager.getIndexedFiles(studyId))); List cohortIds = new LinkedList<>(); - for (CohortMetadata cohort : metadataManager.getCalculatedOrInvalidCohorts(studyId)) { + for (CohortMetadata cohort : metadataManager.getCalculatedOrPartialCohorts(studyId)) { cohortIds.add(cohort.getId()); } registerNewCohorts(studyId, cohortIds); diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/search/SecondaryIndexPendingVariantsDescriptor.java b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/search/SecondaryIndexPendingVariantsDescriptor.java index 604611ca93c..8b5134873ed 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/search/SecondaryIndexPendingVariantsDescriptor.java +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/search/SecondaryIndexPendingVariantsDescriptor.java @@ -61,7 +61,7 @@ public Scan configureScan(Scan scan, VariantStorageMetadataManager metadataManag scan.addColumn(GenomeHelper.COLUMN_FAMILY_BYTES, INDEX_STUDIES.bytes()); for (Integer studyId : metadataManager.getStudyIds()) { scan.addColumn(GenomeHelper.COLUMN_FAMILY_BYTES, VariantPhoenixSchema.getStudyColumn(studyId).bytes()); - for (CohortMetadata cohort : metadataManager.getCalculatedOrInvalidCohorts(studyId)) { + for (CohortMetadata cohort : metadataManager.getCalculatedOrPartialCohorts(studyId)) { scan.addColumn(GenomeHelper.COLUMN_FAMILY_BYTES, VariantPhoenixSchema.getStatsColumn(studyId, cohort.getId()).bytes()); } } From c1b419be45a35e7d3d25512e29c12ac5f5fa3b19 Mon Sep 17 00:00:00 2001 From: JuanfeSanahuja Date: Thu, 9 May 2024 11:39:41 +0200 Subject: [PATCH 64/85] Prepare release 2.12.4.1 --- opencga-analysis/pom.xml | 2 +- opencga-app/pom.xml | 2 +- opencga-catalog/pom.xml | 2 +- opencga-client/pom.xml | 2 +- opencga-clinical/pom.xml | 2 +- opencga-core/pom.xml | 2 +- opencga-master/pom.xml | 2 +- opencga-server/pom.xml | 2 +- opencga-storage/opencga-storage-app/pom.xml | 2 +- opencga-storage/opencga-storage-benchmark/pom.xml | 2 +- opencga-storage/opencga-storage-core/pom.xml | 2 +- .../opencga-storage-hadoop-core/pom.xml | 2 +- .../opencga-storage-hadoop-deps-emr6.1/pom.xml | 2 +- .../opencga-storage-hadoop-deps-hdp2.6/pom.xml | 2 +- .../opencga-storage-hadoop-deps-hdp3.1/pom.xml | 2 +- .../opencga-storage-hadoop-deps/pom.xml | 2 +- opencga-storage/opencga-storage-hadoop/pom.xml | 2 +- opencga-storage/opencga-storage-server/pom.xml | 2 +- opencga-storage/pom.xml | 2 +- opencga-test/pom.xml | 2 +- pom.xml | 6 +++--- 21 files changed, 23 insertions(+), 23 deletions(-) diff --git a/opencga-analysis/pom.xml b/opencga-analysis/pom.xml index 36890fd8b65..e6ff1cdab39 100644 --- a/opencga-analysis/pom.xml +++ b/opencga-analysis/pom.xml @@ -22,7 +22,7 @@ org.opencb.opencga opencga - 2.12.4.1-SNAPSHOT + 2.12.4.1 ../pom.xml diff --git a/opencga-app/pom.xml b/opencga-app/pom.xml index cce6a1832f6..8338fed6637 100644 --- a/opencga-app/pom.xml +++ b/opencga-app/pom.xml @@ -22,7 +22,7 @@ org.opencb.opencga opencga - 2.12.4.1-SNAPSHOT + 2.12.4.1 ../pom.xml diff --git a/opencga-catalog/pom.xml b/opencga-catalog/pom.xml index fa4d079fca2..3c04b120d94 100644 --- a/opencga-catalog/pom.xml +++ b/opencga-catalog/pom.xml @@ -23,7 +23,7 @@ org.opencb.opencga opencga - 2.12.4.1-SNAPSHOT + 2.12.4.1 ../pom.xml diff --git a/opencga-client/pom.xml b/opencga-client/pom.xml index cf8bce68061..6bfc198dbd2 100644 --- a/opencga-client/pom.xml +++ b/opencga-client/pom.xml @@ -22,7 +22,7 @@ org.opencb.opencga opencga - 2.12.4.1-SNAPSHOT + 2.12.4.1 ../pom.xml diff --git a/opencga-clinical/pom.xml b/opencga-clinical/pom.xml index 5e87374579c..091f182629c 100644 --- a/opencga-clinical/pom.xml +++ b/opencga-clinical/pom.xml @@ -5,7 +5,7 @@ org.opencb.opencga opencga - 2.12.4.1-SNAPSHOT + 2.12.4.1 ../pom.xml 4.0.0 diff --git a/opencga-core/pom.xml b/opencga-core/pom.xml index b896c8ef333..aa0b7536f33 100644 --- a/opencga-core/pom.xml +++ b/opencga-core/pom.xml @@ -22,7 +22,7 @@ org.opencb.opencga opencga - 2.12.4.1-SNAPSHOT + 2.12.4.1 ../pom.xml diff --git a/opencga-master/pom.xml b/opencga-master/pom.xml index 0e14a74b9a2..7d734c21008 100644 --- a/opencga-master/pom.xml +++ b/opencga-master/pom.xml @@ -22,7 +22,7 @@ opencga org.opencb.opencga - 2.12.4.1-SNAPSHOT + 2.12.4.1 ../pom.xml diff --git a/opencga-server/pom.xml b/opencga-server/pom.xml index 255d0d1709c..995f35ba347 100644 --- a/opencga-server/pom.xml +++ b/opencga-server/pom.xml @@ -22,7 +22,7 @@ org.opencb.opencga opencga - 2.12.4.1-SNAPSHOT + 2.12.4.1 ../pom.xml diff --git a/opencga-storage/opencga-storage-app/pom.xml b/opencga-storage/opencga-storage-app/pom.xml index f2834ff74ae..94bff4c00ef 100644 --- a/opencga-storage/opencga-storage-app/pom.xml +++ b/opencga-storage/opencga-storage-app/pom.xml @@ -22,7 +22,7 @@ org.opencb.opencga opencga-storage - 2.12.4.1-SNAPSHOT + 2.12.4.1 ../pom.xml diff --git a/opencga-storage/opencga-storage-benchmark/pom.xml b/opencga-storage/opencga-storage-benchmark/pom.xml index 81ae1525c3e..40cf18bfb8c 100644 --- a/opencga-storage/opencga-storage-benchmark/pom.xml +++ b/opencga-storage/opencga-storage-benchmark/pom.xml @@ -22,7 +22,7 @@ opencga-storage org.opencb.opencga - 2.12.4.1-SNAPSHOT + 2.12.4.1 ../pom.xml diff --git a/opencga-storage/opencga-storage-core/pom.xml b/opencga-storage/opencga-storage-core/pom.xml index 83ba931c476..ccf5ad0c257 100644 --- a/opencga-storage/opencga-storage-core/pom.xml +++ b/opencga-storage/opencga-storage-core/pom.xml @@ -22,7 +22,7 @@ org.opencb.opencga opencga-storage - 2.12.4.1-SNAPSHOT + 2.12.4.1 ../pom.xml diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/pom.xml b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/pom.xml index 0cb400c03d3..ded68c578bf 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/pom.xml +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/pom.xml @@ -23,7 +23,7 @@ org.opencb.opencga opencga-storage-hadoop - 2.12.4.1-SNAPSHOT + 2.12.4.1 ../pom.xml diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-deps/opencga-storage-hadoop-deps-emr6.1/pom.xml b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-deps/opencga-storage-hadoop-deps-emr6.1/pom.xml index be258210e4f..28d392a9ea7 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-deps/opencga-storage-hadoop-deps-emr6.1/pom.xml +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-deps/opencga-storage-hadoop-deps-emr6.1/pom.xml @@ -22,7 +22,7 @@ org.opencb.opencga opencga-storage-hadoop-deps - 2.12.4.1-SNAPSHOT + 2.12.4.1 ../pom.xml diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-deps/opencga-storage-hadoop-deps-hdp2.6/pom.xml b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-deps/opencga-storage-hadoop-deps-hdp2.6/pom.xml index 7ce0441a47d..5c40b34b0b9 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-deps/opencga-storage-hadoop-deps-hdp2.6/pom.xml +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-deps/opencga-storage-hadoop-deps-hdp2.6/pom.xml @@ -22,7 +22,7 @@ org.opencb.opencga opencga-storage-hadoop-deps - 2.12.4.1-SNAPSHOT + 2.12.4.1 ../pom.xml diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-deps/opencga-storage-hadoop-deps-hdp3.1/pom.xml b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-deps/opencga-storage-hadoop-deps-hdp3.1/pom.xml index cf4bb3c0833..ed33bf0043b 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-deps/opencga-storage-hadoop-deps-hdp3.1/pom.xml +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-deps/opencga-storage-hadoop-deps-hdp3.1/pom.xml @@ -22,7 +22,7 @@ org.opencb.opencga opencga-storage-hadoop-deps - 2.12.4.1-SNAPSHOT + 2.12.4.1 ../pom.xml diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-deps/pom.xml b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-deps/pom.xml index a2124179531..bb718594f50 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-deps/pom.xml +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-deps/pom.xml @@ -50,7 +50,7 @@ org.opencb.opencga opencga-storage-hadoop - 2.12.4.1-SNAPSHOT + 2.12.4.1 ../pom.xml diff --git a/opencga-storage/opencga-storage-hadoop/pom.xml b/opencga-storage/opencga-storage-hadoop/pom.xml index 364447c5d26..510bd72eaac 100644 --- a/opencga-storage/opencga-storage-hadoop/pom.xml +++ b/opencga-storage/opencga-storage-hadoop/pom.xml @@ -28,7 +28,7 @@ org.opencb.opencga opencga-storage - 2.12.4.1-SNAPSHOT + 2.12.4.1 ../pom.xml diff --git a/opencga-storage/opencga-storage-server/pom.xml b/opencga-storage/opencga-storage-server/pom.xml index d07a2556ef6..a3fe6497eb8 100644 --- a/opencga-storage/opencga-storage-server/pom.xml +++ b/opencga-storage/opencga-storage-server/pom.xml @@ -22,7 +22,7 @@ org.opencb.opencga opencga-storage - 2.12.4.1-SNAPSHOT + 2.12.4.1 ../pom.xml diff --git a/opencga-storage/pom.xml b/opencga-storage/pom.xml index 8af319c168b..3284f8c8670 100644 --- a/opencga-storage/pom.xml +++ b/opencga-storage/pom.xml @@ -22,7 +22,7 @@ org.opencb.opencga opencga - 2.12.4.1-SNAPSHOT + 2.12.4.1 ../pom.xml diff --git a/opencga-test/pom.xml b/opencga-test/pom.xml index fd776c8408b..6baa1797a71 100644 --- a/opencga-test/pom.xml +++ b/opencga-test/pom.xml @@ -24,7 +24,7 @@ org.opencb.opencga opencga - 2.12.4.1-SNAPSHOT + 2.12.4.1 ../pom.xml diff --git a/pom.xml b/pom.xml index bd0b2b56ab6..60f9eabe132 100644 --- a/pom.xml +++ b/pom.xml @@ -22,7 +22,7 @@ org.opencb.opencga opencga - 2.12.4.1-SNAPSHOT + 2.12.4.1 pom OpenCGA @@ -43,8 +43,8 @@ - 2.12.4 - 2.12.4 + + 2.12.4.1 5.8.3 2.12.2 4.12.0 From 1bf4ec594f23f052186155cfcb5f99cbb17f68c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacobo=20Coll=20Morag=C3=B3n?= Date: Fri, 10 May 2024 18:20:05 +0100 Subject: [PATCH 65/85] storage: Hash large ref/alt alleles. Add new column ALLELES. #TASK-6005 --- .../variant/VariantStorageEngineSVTest.java | 17 +++- .../test/resources/variant-test-sv-large.vcf | 52 ++++++++++ .../adaptors/VariantHBaseQueryParser.java | 9 +- .../phoenix/VariantPhoenixKeyFactory.java | 98 ++++++++++++++++--- .../phoenix/VariantPhoenixSchema.java | 1 + .../phoenix/VariantSqlQueryParser.java | 28 +++++- .../sample/HBaseVariantSampleDataManager.java | 2 + .../AnnotationPendingVariantsDescriptor.java | 18 +++- .../converters/HBaseToVariantConverter.java | 5 +- .../hadoop/variant/converters/VariantRow.java | 22 ++++- .../study/StudyEntryToHBaseConverter.java | 1 + .../gaps/PrepareFillMissingMapper.java | 2 +- .../VariantTableSampleIndexOrderMapper.java | 4 +- .../variant/index/sample/AlleleCodec.java | 8 +- .../sample/SampleIndexVariantBiConverter.java | 4 +- .../mr/SampleIndexTableRecordReader.java | 13 +-- .../pending/PendingVariantsDescriptor.java | 7 ++ .../pending/PendingVariantsReader.java | 2 +- .../variant/prune/VariantPruneDriver.java | 24 +++-- .../variant/prune/VariantPruneManager.java | 2 +- ...condaryIndexPendingVariantsDescriptor.java | 1 + .../stats/CheckVariantStatsDriver.java | 2 +- .../stats/VariantStatsFromResultMapper.java | 2 +- .../HadoopVariantStorageEngineSVTest.java | 37 ++++--- .../VariantHadoopStoragePipelineTest.java | 2 +- .../hadoop/variant/VariantHbaseTestUtils.java | 6 +- .../phoenix/VariantPhoenixKeyFactoryTest.java | 42 +++++++- .../hadoop/variant/gaps/FillGapsTest.java | 3 +- 28 files changed, 333 insertions(+), 81 deletions(-) create mode 100644 opencga-storage/opencga-storage-core/src/test/resources/variant-test-sv-large.vcf diff --git a/opencga-storage/opencga-storage-core/src/test/java/org/opencb/opencga/storage/core/variant/VariantStorageEngineSVTest.java b/opencga-storage/opencga-storage-core/src/test/java/org/opencb/opencga/storage/core/variant/VariantStorageEngineSVTest.java index fe7cebbd6a4..44ccd4f305a 100644 --- a/opencga-storage/opencga-storage-core/src/test/java/org/opencb/opencga/storage/core/variant/VariantStorageEngineSVTest.java +++ b/opencga-storage/opencga-storage-core/src/test/java/org/opencb/opencga/storage/core/variant/VariantStorageEngineSVTest.java @@ -16,6 +16,7 @@ import org.opencb.opencga.storage.core.StoragePipelineResult; import org.opencb.opencga.storage.core.exceptions.StorageEngineException; import org.opencb.opencga.storage.core.metadata.models.StudyMetadata; +import org.opencb.opencga.storage.core.variant.adaptors.VariantQuery; import org.opencb.opencga.storage.core.variant.adaptors.VariantQueryParam; import org.opencb.opencga.storage.core.variant.adaptors.iterators.VariantDBIterator; import org.opencb.opencga.storage.core.variant.io.VariantWriterFactory; @@ -39,11 +40,14 @@ public abstract class VariantStorageEngineSVTest extends VariantStorageBaseTest { protected static StudyMetadata studyMetadata; + protected static StudyMetadata studyMetadata2; protected static boolean loaded = false; protected static StoragePipelineResult pipelineResult1; protected static StoragePipelineResult pipelineResult2; + protected static StoragePipelineResult pipelineResult3; protected static URI input1; protected static URI input2; + protected static URI input3; @Before public void before() throws Exception { @@ -72,6 +76,12 @@ protected void loadFiles() throws Exception { pipelineResult2 = runDefaultETL(input2, variantStorageEngine, studyMetadata, new QueryOptions() .append(VariantStorageOptions.ANNOTATE.key(), true) .append(VariantStorageOptions.ASSEMBLY.key(), "grch38")); + + input3 = getResourceUri("variant-test-sv-large.vcf"); + studyMetadata2 = new StudyMetadata(2, "s2"); + pipelineResult3 = runDefaultETL(input3, variantStorageEngine, studyMetadata2, new QueryOptions() + .append(VariantStorageOptions.ANNOTATE.key(), false) + .append(VariantStorageOptions.ASSEMBLY.key(), "grch38")); } @Test @@ -88,7 +98,7 @@ public void checkCount() throws Exception { + 1 + 1 // negative cipos ; - int count = variantStorageEngine.getDBAdaptor().count().first().intValue(); + int count = variantStorageEngine.count(new VariantQuery().study(studyMetadata.getName())).first().intValue(); assertEquals(expected, count); } @@ -146,7 +156,10 @@ protected void checkCorrectness(URI file) throws StorageEngineException, NonStan @Test public void exportVcf() throws Exception { - variantStorageEngine.exportData(null, VariantWriterFactory.VariantOutputFormat.VCF, null, new Query(VariantQueryParam.UNKNOWN_GENOTYPE.key(), "./."), new QueryOptions(QueryOptions.SORT, true)); + variantStorageEngine.exportData(null, VariantWriterFactory.VariantOutputFormat.VCF, null, + new VariantQuery().unknownGenotype("./.").study(studyMetadata.getName()), new QueryOptions(QueryOptions.SORT, true)); + variantStorageEngine.exportData(null, VariantWriterFactory.VariantOutputFormat.VCF, null, + new VariantQuery().unknownGenotype("./.").study(studyMetadata2.getName()), new QueryOptions(QueryOptions.SORT, true)); } protected Map readVariants(URI input) throws StorageEngineException, NonStandardCompliantSampleField { diff --git a/opencga-storage/opencga-storage-core/src/test/resources/variant-test-sv-large.vcf b/opencga-storage/opencga-storage-core/src/test/resources/variant-test-sv-large.vcf new file mode 100644 index 00000000000..5e1de5845e2 --- /dev/null +++ b/opencga-storage/opencga-storage-core/src/test/resources/variant-test-sv-large.vcf @@ -0,0 +1,52 @@ +##fileformat=VCFv4.2 +##FILTER= +##FORMAT= +##FORMAT= +##FORMAT= +##FORMAT= +##FORMAT= +##FORMAT= +##FORMAT= +##FORMAT= +##INFO= +##INFO= +##INFO= +##INFO= +##INFO= +##INFO= +##INFO= +##INFO= +##INFO= +##INFO= +##ALT= +##ALT= +##ALT= +##ALT= +##ALT= +##ALT= +##ALT= +##ALT= +##ALT= +##ALT= +##ALT= +##ALT= +##ALT= +##ALT= +##ALT= +##ALT= +##ALT= +##ALT= +##ALT= +##ALT= +##ALT= +#CHROM POS ID REF ALT QUAL FILTER INFO FORMAT SAMPLE_3 SAMPLE_4 +20 500000 . C CCCCGTTTATGAACTCAGCGCCGAACAGAAAAAATAGCCCCACTTTAAGTCCGCTTTAGCGACTCTAGGGTCCGAACGCGCTGTTTCGTACATGGCACGTCGGTAGGCAAGAACTCCCGTCCTCAGATGAAGATGCGTAATATCCTTACGTATTTTGGAACTCAGGCTGCCGAGCATCTTATTGGGAGACTCTTACCACTTTGCCCGTAAGCAGGGAAACGACATTTGATAAAGGATGGCAGGGAAGCTTTTATGCCCCTTTTCCTACTACAACGTCGAATGTTGACTTCCTGGTTAGCGTTGTGGCCTTGTACTGACCCTACTAGGGTTTCAGCTGCCTAGAGGACATTCGACCGACCCACGACCGCAGCTCGCGGTTCATACACGAGAAGCTACAATCCGCTTAAGTATTTGTTCTTTTCGTTCTAGGGCCCGCGGCACCAAGGAGGCTTCAGAAAGAGAATAATTACTCGATCGTCCCGTAAGTAGTGTATCGCTAACAGGGCCTGCGTCGTCCATACTAAGGCAAGGTGCTCCAGCAGGGCATAGGAATTGACCGGCGGGTAACATTGGAGACAACATGTGATTTGTTGCTTAATCTCGGTTAACCCGCCCCGCTGTAAAGGCGAGACGGCAATCATGAATTCTAGCACGCACCCCGCCCGTCTCTGTCTTCAAAATGTATTTTTGGCAACGAAGGATCAGCCTGTCCCGAATCGACACTGTGTTCCTATGGCGTAAAGAATTCTGTTCCTGAATCGCGGGCGCACCGTAATTCTTACTTTCACATCGAATTGTTAGATGCTGACGAGCAGAGCGCAGTGCGGCCGGGCGGAGATTGCAGGGCTGGCAGAGCCATTGGCCGTTGATGGTGTTTAGACGCTAAGCTAACCCTATGCCTCATGGATACTTGCTACACAACAGTGTCTGCGTAGGCTGAAATGGGGACGGCATGAGACCTCAGTGTCAACACAATTTGATGCACTGGGTTTTCTGCAACTACTTTACTACGGCTTTGTCCTTAACGCGTTAAGGGACTCCATCTCATCCGTATCATAAACTCCGTAGTGTATTGGGGCCAAATCTAGAATACGTACCGTCGACAATGCTCACGAGGGTTACTCAAAACTCGGCGGGGTGCCTCAATCCGCGTGCCGTGAAATGCCCGTATTCACGACGACTAAGCACTTAAGTCTCGGGAGCTCTGTTGCGTCTCGTCTAAGGGCAGTCTTGCTTCCTGTGTCTGCAAGTTCCTCTCTAGTGTTTAGGGTGCCTAATATACTCCACGTGTGTCTATGGACTCCATATGGTAAGTAATGGTGTTTGATAAACCCCTGGCCCTTTAGGTTCTACCTAGCCTAACTTCTTCCTTTGACTTTTACCCCCATTGATCCATGTTCGTCGAAGTGGCCGATTGAGGCTGCCGCATGGCCAAACCGCTAACCCGATCGAGAAGGTTGCAAGGGCGCATCCGCAAATAAACCATGGTTGCTAATTGGGGTGCAGGCGTAGAATTTGTCGGTTCAAAAGGCCCTCGACCTGCACAATGACTTGCGCTCGTAACTTATGATAGGGCCGGCATGGGATTATTCGAGGGACTCCTCACACTCAGAAGTTTACTCCCGGAGCACGACTTTACGAGGTGTGTTGCTTTATGATGGCATATAAAAAAGATGCACCAATCACCAAAACCCAACTATCCTTGACACGATCAGTGCGCGACCTACGACTACTCTAGTGGTACGACTATCGCGATGGAGGGGATATTCGTATATTTGAAGTTCATGTATTGATTCGGTTATGGCGTCTCCCTTAGTGTTTATGGACTTCATGCGTGCCCCTTATCCGCCCGCAGGCACCAATCACATTGTGGAGTTAGTTGGAGCGAAATTGGGTGGCTGTACGGTCAAACTAGAAGCATACCTTCACAAGGGCGTGGCGCTATGGGAAGTGGACCTGAGGGACACGATGGGTGAGATTCGGACACTCTGTCTACAAAATTAGGAGGTACCTACTGCTAGCGAGCTTCAAAATTCGGGAAGAGATCCTCGTACCACGTATTAATGAAGAGCCAGTGGAGCGAAGAAATTATCGCAAGACCGACCCTGTGCCGGCAGATGGACGTGTTAAACATGGTACATTGAGCAGTCCGACTCGTTGTATAGTTACCACGTGTGAGAAGACTTAGCTCGCAGCTAGTGGACAAGAACTCGGCCGAAGTTTCGTTCCTGTATTGCGCGTGTCCAGGATGTGAACAGTCCAACTTCATTATTTTATTCTGACTTGACACTGGACGTAAGTCAGCTGCTCAGAAACCGGAGTTCCCTGCCTTGGCCTGGGGGCCCCATTTGCGGATGAGCCCACAGGTCTCGTAGACTTAGGTGACGCCGGGATCTGCTGGCCTTATGTCCCTAGAAGCTTGGATGACCGGCCCACGGCAATGCGTAGTCAGGGAGGTATCCATGACGTGCGTGAGTCGGGCGAAGAGGGCCCCACATGCACCTAGAATAGCTATGTGTGTTTCTCGGGCGGAGCCCGACGTCGTCCCGCTCATATCCAAGTGCTTTTTCCGGGGGTTAAGCGGTGGCTTGGGCACAAACGGTCGCCTCCGCCCGCTTGGTCTCTCAGGTATTTCCGGGGGCACTCATAAACTACGAACGCGATCTCCGATAGCCTTCAGTTGTGGGGATGCGGCTAAATCCAAGCAATTGCGACGCTTTGGGTGTGGTGGGGGTTACTGATCCGGACTGCAAATTACTAACTCCGTCACCTATCAACACGTCTCCCTAATCTGTTGGAACCTCGCTCTATGACATCAGAATGCGAGCGCGGACATGGGACATGTCGGGACAATCTATTCTGCCTCTCCGGTACTGGGTACGATAAGCGCGACACAAGATTGTGCTCTTACTTCGCCGTGTTACCGGGTAAATCGCCGGGATGCTACTCTTATATGTGCCTTCTCACCTGAAGCCTTGCGACCTCGAATGATTTGGGTGTGAGTAAGCACCCGGGATCGAAGCTGGTAAGCACGTCACCATGTTAGAGATACTTGACCGACGATGCCCTTCTACGGCTCGGTTCACGGTGCCCAGCGGGATCCTCTTATCCCAGCCGGTGCCTAGCCGATAAAAGCTCACAAGCTTAAGGCTCTGTCAGGGGAGATGTGGGAGAGGCTCGATGAGAAGTCCTAACGACACCAGAACCCCAATTAGCACACATGGCTCTTCCGGGGACTTGGCTCTCGTAACTGCCTGCAATGTACTACGTCGCATGCTCATGTACCAGACATTATGTCCGTCCTTAACAGTCGTATTGGAGCAAGTTGTGAGTACAAACAGTACACAAGCTGTAGGTCACTCCCCCCACGTCTACCCTATATACTATAAGTCCTTGTAGCCAGGATGAGTAGGCCCCGTGTACCTTATTTGAATGCGCACCCGTGACTTCTGGTGGAGAACTTGGTCACGTCGGGTGGACCGTGTACGATACCCCACAGTGCCCCAGGAGGTATGGAACGATGCTGCCCTGAAAGGTGGAAGGCCGGAGTTTTTGTAGTTACAAACAGTACTCAGCGCTATCAGCAAGTGGACACGGAGAAGTAATTGAATGACCGCCTAGCAGTGCTCCGCCTCCGGGCGGCAGCCCGCGTGCCTCAGTCAGAGATCTCGAGCACGCACCCTTGCTGCTTCCGACTAATGGGAAGAAGTGGAGATGGCGACCCCCACGCGTTATAGTCCCAAGGTTGCTTCCAGGAGCTATACCCGAACCTTTAGGTCTAGACTTGTCGAGTTTGCGACCGTACTCGCTTTGTATGTCGACTTTTTTGAAAAGACAACCGTGGCCCGGTCACTGTGTCTCCAGTTTGGCGAGCCGTAGTCAGTGATCGCGCTGCTCGGGATCAATTATCTCCAACGGTCAGCAGATCTACGGAGTCGGTGGCCGGTATAATGCTGGAGGCCGGTGTATGCAGGAACCTAATAGTCCCCGAGTGTCGATCTGTACGGGAGTCACTAAGATAAGGCAGAACTGACTATCTCTCCACCGCTACGTAGTCCAGTGCCAAGGTGTGGTCATGGCCCACATAAATCAAGGATTTGTATGCTAGAATTACGCGATCGAGTGACACTCAGAGTGCACTGGCTAAGGACTCTAGCTTTGTAAAGACAGCATTACATCAACACTCGTTGCATTCCTAGACTGCGGTTCCTTCGGGATCTCCCCTTGGTACTTCCTATATTTCCTGAGATGTGGGCGCAAACAAATGCCAGATCCCGCCTGTAGGCATTCGGGACGGGTACTACGCGATGACCATATCGAGATTGAATCTTACGTATCTCCCTACAAGTGTGGCTTAAGGGGTTAGCACCGACAACTCATATAAAAACCAAGTAAAGAGAGTAAACACAGTGCGGAGTAGCCGTACTTGCGAAGCGCCATTTGGGCGCGACCTTCCGAATTTGCATCCGACGTCGGTCGTATAGCAAAGAGCGATTCTGAGCCTCCAGTCGCGGCCACGTCGCCGCTTGGCCAATGTATACCAGTTGTGAATAGGTCGCGGAACGCTAATGGAAGTAACCCCTCCTATTACCAACACGCCTCAATCGTACCACCGGTACCCACGGCATATAGAGACTATACGGCGTCGCGGCGGGCCTCCTCATGCTCGTATGGACTACACACCATGTCCTAATAACCTTGGTAACATTACGCCTTTGAGGGGTTCTTTATCTCCGATTTCGCGGTAGATAAGGCCACATGACATTTTCCGTTCGAGCGGACACGTGTCGCCTCAGTAGCCTATTGCCGTCGCCCAACCTACGCCACTGGCTCATGCCATGCCATCTCATACAATTAACTCCCGACGTTCGTACCAGGTGTACCAGGGGGTCCATACTAAGAGAGTGTGACCTCCAGATTCTAAAATACTATGTGAGGAAGTCATGATTTCCTCTAGTCATTGTGGCACCGCTCGTACCGTGAATCATATCAGATAAGAACGATCAGTTTGCGACTGTTATTCCGAGGGTACAGTCTTTAAGACACCATTCGGAAACGAAAAGGGACTAATGGATGCCGCGAAAAACCTAAAAAGGAAACAAGCTATCGATCTGTGGCGCCAAGGAGGGCGGGGCCCCGCATGACTCGTCAACTCCCATAGGCACCGCTCCGGGCCGGTAGCGACCGGAAGGCAATTGCTACCCTATCATATAAATGATCCTGGTCATTAGTTGTGCCCCGTATACTTGAGTCAAGTATTCCGTCGCAGAGACTACTGCTCATCCGAGACAACTTCTTCTCTAAGCGACCCGGGCGGACAAATTCACACGCAGATGGGAATTACACTAGGGGTATACTCACCCGGGCCTAAGGAAGGCACATGAGTGGGGCGGGCTGATTAGCAATTGTATCAAACTAGGGTCAGGCACACATAATGAAGGAGCAAATACATTGCACGGATATAGCCTAGTCGAGTTCGACGCGGAAGAGGTAGGCGAAATAAACTGTGAAAATGGGCAACACCTCACGAATGGTCATGAGTCAATGTAAAATCTTCGCGGCTTACTCGGCCTATTGCTATCGTGACTCCCAGGCCCTCAGTCCACCTCTCGTCAGATACTAGTTCGGGAGGCTCGAGATAATTGACCCTCCCTAATTCAAACTCAAACGAACTCACGTACGGGTAGGGCACCTAATTCGAGATGAAACATGCCTAAACGCCTCGAGAATATGTCTGTTTTGTACATAGTCTGTCGCTTATTCCACCACTTCAATCTGAAAATAGCGGACTAGTCCCGAGGGCCCCGATTTGACAGGTGGTTGAGAAGATCAAGTTGCACGCTAGCACCAGACCCTAACTCGCAACTGCTCTGCCTGATAAAAAACACATGAATCTGCGAACCATAACCTTCTTTGCCATTCTTTGTCTGCGGTTAGCGATGGGGGGTGTAAAACCACCTGCAGCGCGTCCCGATGATAAGCTATATGGGTTCACGTGCAATCCCAGAATCCTTTGGGGGGTGGATCAAATTGAAGCGAACGCAGCGTTGTATCGACGGTGAGCCCGCACATTTGAACTCGTTCCTCGGGTTCTTCGATGAATGTGGACTACGCTAGTTGACAATGCCTGCAAGTCTCCTCTCTCCCCCACGTGTAATATTGTACATAGTCAAGAAAGCTACATGCACGCCGACGTATCTTCTGTGCTTATGGATCGTTATAAAATTTTGTACTTACAGTGAAAATATGAAGGATGAAGCCTTAGAACTCGCTGCGTGAGAGAGAAACCCACCTATAACAAGACGCACGTGGCGCACATCCGTCCCCAGTGTTCAGCGACAGTTTGTCTAGCCAGTGAATCGGATCAGGCGGTCCTAGAGGTCTAGGCGACTTATGATCTTAGTCAGTAACCCCAGTAATTACCGTGATTACCATTTACAACGGTTAATTGGGTTGGTCTATGGTAACGCACAAATTACTCGTCATACCTGCTTAACATGCCTTCGGGAGTTAACGCTGTCGGGCGGGGTCAGCTTACATTACAGTAATCCGGCAAAAGACAAACCAATGCATCTCAAGAACCAACATAATAAAAAGCCTTATCAAATCTGGATCACAACTAAACGTATCACAGTAATATGTATCGCGAGTCTAGGAACTTGAGCACCCAATCATCATCCGTGGCGTCTCCGCGGGCTCTGAACGAGAAAACTGGGCACTCCCGGCTACTTTGAAATCAGGAAAAGGTCATCTGTTAAATGTCTGTTCACGATAATAGGCTATTCCACTTCAATACATGAATGACTTAGGATAGATATTCCCCTGGGCACGATGTTCTTATGGAGTGCGGGATTTAGTGGATATTCACGCTTGTATTCAGTCCCCTGTCCCATCACCTTTTTATTTGTCCTCCGCCCGGATTCGTTTCGTGCACGGCCAACGAGGAGCTGTTCATCAAATCTACCGACATTAATAAGTCTGGCCTATATGTCGTCCAACTAGGGACCCCTTTCAGAGTAGGTGGAGCTATCGTAGTCATCAAGTCACAAAATGAGTTCCTTTAAGGTGGCGATGTGTTGGGTGCAGACAGTATAGATAACACTCGGCATGGCTTTAGTCCCTCTATCTCGGATGCGCGCATCACAGATACCGCACAGGGTCCCACCTTACATGTTCGGTTGGGACTGAGTGGAAAAGTTGGACCCTAATGGTTGCTTCCGCGAGAACAGAGACTTGAAGCAGTCAGTCAGGGATTCAGTCCGTCAGATAGGGGTGGAAGTATGGCCGGCGGCCATTTGAAGTCGGCTAGCAGCAAATAAATTGCGTAAATATGTTGGTGTTTGGGACAAGGAGGCACGGATCCAGACGTTACTGAGTCCCCGAAAGCGTTACTCACGGATACACGCCATACGCTCTACTAAGAAGAACCATGCACGGACCATTCGATACAGTCTTTCAAACGCCAATGAACCAGGAGCCGGGGGGATGAAGGTGGGTTGGAGGCATCGGAGTGGTTGGGAACTGGTAAACGAGAAGGCCTAAGAGTACTCCCAACGCGGTGGGTAGTATGTAGGTTGGTTTAAGTCGCGTTATCTGGAGCCCGATACAGAAGACCATCAGCTAAGAGTGGTCGTAAGACAACAGATAATCCAGGCATACTAACACCGTTTTATTAACACCTAACCCGTGCGCGGGCAATGATCTGTGATTTCGGCGGAACCCTTTAGCAATCACTCGAATGCTCCCCTCAAATTTGAAAGGCATGACCTCCGTTGTACGCCCTGGATTTCTTAGGGATCGATTAAATTGGAGGCGAATCGTGTGTCTGATCTATTGGCCAATTTGATAAATCGGGACAGAAAACCCTGGGCAGCTGTATCCCGGCCAACTTGACTTTCACCTTTATGCTATCAGAAAAATCGGTGAAACTGAAAGTCTCTGAAGTTCTCTGCAGTCATGCGGGTACACGAATGTGAATATGAGCTGTCGCGAGTTAATAGGACAGGCAGAAGCGCAGGTTGCGTCCTAACAGGAATACTCTTAAAGTAGGTGCGAATCGAGCAACGTCATCGCGTCAAGCGCGACCGCTTCAGTTGGTTGGAGGCTGTCGGCAGGTTCATCTTGCCAAATCGAACTAGCAGTGGCTTCGTTACGGGCCAATACCACCTCGAGGAACCCGGGTAATGAGGTACAGCTTACACAGGCAACCTGACAGAATGGATGTTTGACCTTCTATGCTGTACGTGTTAGCCCAACACAATTAGCAAGATTGCACCGGCGCTAACAATGTTAATGAGGTGTACTAAAGAGGTCGTACAGACAGGTCATGGGGGTAGGCGTATTTTCGCGCAGAACACGGGTCTATCCCATGAACGTACAGGCAAAATATTCGTTCTAGGAGCTGTGGGTCGGTTCCGTGGAGAAAAGTCGCAAGGCTATGTAAGCATTCATGCCTAATCCTCGCAAAAAGTGTGTGGGATTAGAAGCGTGTCTGAGCAGATGTGGTGCGGGATCGAAATAAGTAGGTAACTACCACAGCACACTATTCCAAGCAATAGTTCGAAAAAGGAAGACAAACCGATTCGGTTAAACTTGTGGCGGTCCTTTATTGCGCTAGCGTGCACATACTTATAACCGTTCCTTGCTAGATGCCAATACACGATATTGGCACATCAGGTGCTTTCACCCGAGACAAACGGCCTCTGCTAGCAATCCCGGGTCGGTAAAAATAGAAGACGAGAGGACGGCGATCATATCGTGCGAATAGTATCAGGCTTCATATGGGCAGTTCGCCTCGAGGACTACCCTCGTCGAAAAGCTTTACCGGAAGATGCCAAACCCGGGCAGCGGCACCAGGCTGTTACCCGTACTCCTAATAGCTCGGCTAAAACACGGAGAATGAAATACCTGTACCAAACGCACGTTGAGCTTCATCCACCTCTGGCGTGTGTACTATCCTATAGCGGATTTCGCCGGAGTTGCCTTTTCTCCTTGAGTGTTGATGCTGCCTTCTAACAAGCGCCTTTGCACCCAACATCGACATTTAAACTTTATTATGGGGTTGGTCCTGCTCCGTGCAACTGTCCTCTCTGTCACCACTATATTAAACATAGTCTGACCTAATGCAAGTTAGTAAGGAACAAGAGCAGCCTCATAAAGACTTGGCGACGCGTTGAGACACATATTGGGTACTTTAGGGATAATAAGTGTGAGGTACGAGGTGCGCGGACATTATCTTGATGCCCTTCTTGGAAATGTCGTATTTCAGGCCCCTGGTGCGGAAGAACTTTGGCCGGGTTTACATAGTTTAGATAGTCCTAGGTACATCAAGACGCCAGTATGAGTCCGCGAGCCGGTATGAGTCATATACAAGCCAAAGGGCCGCCTCCAACTTCTGTATCCGTAATTTTCTCCATAGGGCTCTGACCAGTATTGACCCCAAAATGTGGGCTGCAGATCCAAAGAGTTAACGGTACTACCCGAGGGATCAGTCATTCACTACGGTGCGCCTTGGATGGGATCCTACCGTTGAATTCGTAGCCTCCTGCGCTCCGCTAACCCTGACAATATGTGCACTTCGCCTGGACGTATTGACACCTGAAACGAGCACTGAGCGTAAAGCTAGTTGTTATACGTCACTGCACCATGTGGCGGGTTATAGCATCCTCCCATTTAGGTAATGCGAATCTTCACAGACATGACGGGGCATGTGGACTTACCGGTTACTTCGGGAAAACTGGCAGACAAAGGTTGGTTATAACCTACCAGCAAGTCATAATCTGTTTCAGGAATTACGCAGTTCTGCCGCTCATCCTAAAAATCCACCGACCCTCGCACGTGCCGAGTTAATCTACGGAACGCATAAGAGAACGGAAGCCCAACTGGAAGTTGGACAATGCCATGAGCGCCCTCGGACCACCCTCAGAGAGGTAATTTAGGGGAGCTAGGTAATGATCACGCTTTTCAGTGGTCCTGTATCGTGCATAGGGAAACCACTCTGGATAGTGCTTCTAGCGAATCGTCTAAGTACCCCATCCTTATAGCCCTGCCAAAGTGCTGGTAGTAGCTATCCGGATCACCACGTTCGGGGGACGGGGCGTGGCTCGTCCGTATGCTGGCTTCGCCGTAGCGCAGTCCGAAAACTGACAGACATAGTGCATTAGCATTTAAACCACCTCGAATAAGATTTGGGCAGATAATAGCGCCATCGTGTGCACTTGTTGCTCGGTGCCACCTAACCCCGAAGCTCCTAAGGCGCGGGCCTATAATCGTTATCCCCTACGAAATGCAAGTGCGTCCTTGCTAGAATCATTTGACTCTCCAGGGCCGGGAGTGATAGACCTTTTCAGATGTGTACCCAACGATGGGTTCCTACTCACGTAGATACCAGTTCAACCGCATAACCGTGAATTTTGGTCCGTGTCGTGGACGCCCGGAATGATAAGCCTCAACAGATTGCCTGTTTAGCTGGTCGATTGTGCCGATCAAGTTGACGTGCTAGGCCGGCGCTAAGCGTAGAGGAGAAATCTCGCAGCTTCGATACACGCGAGAACTTGGGCGTCACTTACATAGTCGGAGGTGTCATGGTTGAGCCGGTATCTCCGATTGATCACTCGGGACCAAACTCTATCTTCCTTCTAGAATCATCACGCCGACTTGAACACTGTCGTCGTTTATCACTGATAACGCTTATCAGGTTACGTGGAATCGAAGGTTCAAGACGGTCATGGAGCTGTTTTCTATTATTTCACTGTTAGTTCTTGGATACTGGCGAAGGACGCGCCACTTAGACTGTGCAGTCCCCAATTGGCTCGAGATTCCATCGGCGCGTCTACCTGACTCAATGCGTTACAGTCTTGGCCTGGCGCTCCTACCCCTGCGGCCTATAACGAGGTGGCTGTCCCGCGTGCAACACTCGCGAGCAACATGCCAAGACTTAGGTATAATAGCTTAAAGGTGTTCGCTTCTTGGTAGATAATTCTGGATCCGCGTGCCCACCTCCCTGTGCTACGAAGTTCCGTGAACAATGTCTAGATGTATAGCAGTGTGCAAGCCACCAGGTTCTATGGTGAGCAGCAATACAAGCCGTAGGTGACGTTCGGAATGACCCGCAATTTGTCGCGCCCCAGAGTAAAGCGAAGGCTTGACACTCCCGACTAGTAATCCCATGTGTAGGCCCCAGCACTAAAACATCTCGTTCCTCCTCACTTCCTGTGCTCAAGCCGCCTGGGGTCGAGGCGTAAGTACGGTCTTGATTGGTTGATTTTTGGACAATATGATGTCTCTACCAGCAACGCCGCCACCGGTTATGTCAGTCTCTGAGTTATAGCTACAATCTCAAGAATGTCGTGCGGCTCCCGTGGATGGCAGACGAGTCAAGACCAATAACAGACGTGTGGCACCTCTGGTCGTATCGTCACCCCCAATTGATGAAAATGTGGCTAGAGTTCCGAGGAGGACTTGCAAAACGAGTATCATTGATCCAGCCCATTACTCCAGTGTCCAAGCCCGAAACTGTAAGAGGGCCATTGAAATAATACCGGCTAAGGAATGTCTCGGGCGTGCGGGAATCATAAGGATCCCTCAGTTGACGATTGGGCGCCTCTTTTGCGAGCGGCATCCGCTGCATCGAGGTAAATATGTGTTGGGGACACAAGCCGGATTGGCATTGCCGGAACTTATGTGCGGCAATTGCAAAAGTCGAGTACTAGAAGGATGATCAATTGCCGATGCGCCAATTGAAGATGATCGCCTAAATTGGCTTGTTCATCCTTCGCTCCTGTACGAAGAACTCTATCCAACAGTTGATGGTTGGCAGTAGTTCCGCACGAACAACAACGGGATGGAATTCACGGACATGTTGGTGCCTAAACTAGCGCCGGTTTACCGGACGTGTCCGTACTCATTCCCGCCGCGCCAGCCAGAAAGGGTCGATAATTGCAACCTCTCTCGCAGTATCCTTTGGTCGGCAGAACGCCATGGAGCGATCTCCTATCTCTCAAGGTCAGTTTAAGAATTATGAAGTACTTCTCGACGTGTTGAACTTCCGGTCTCGGCCGTTAGGCTCGCTCGATTGAAGTACAACAGAATTCAGTTTAACCTACTACTCGCCCCAGAGTACTTCCTATGAATGGCTGAACTCTGACACCGAGTAGACAAGTGGTGGATATACTCTTTACGGGAGTCACGTATATCGTACTATTATGTTTCAACGGTGCTTGCCATCCACCACAACACCGGTAAGATTATCAACGCTTACTCTCAATATTGCCCGCGAGGAGGTCTTATCCAAGGTGTAACAATAGTAGTCTGTAGCGTTGAGATTAGTCTTAGAAACGGTGAAGGGCGTTCTCGTGCGCTCGATACCGCTCCCCCCCAATCGTGTTCGGCATCACTAGGACATACAGCGGTCGCCAAAGCCTTTCACCGGTATCGCTTCTCGGGACTGATGCTGCAATACACGCGTAGTCGAAGCAAATTTATGGTGCCCAGCATCTGAAGCAACTCCATAACTTTTACCGTCGATAACAGGATTTGGTAGTCCGCTCGGTACTAATGCCGCAAAATGAAGCCCTATAATGAGATATCCTAAGGACGTAGGGCGCCATTGTTGGTTAATTCCCCCTACGGATTGACGGGCCGCGCCGTCGGGCTGGGGTTCGTATGAACCTAGCTCCACGCCAAGACCTGTCCCTTGTCATAGCCAACAGGACACCTTTCATTATGGCGCTACGCATATGCGACTGTTCCCACAGTACAATGATGTGCTTAACCATCGTCGCTCGGCGATAGGGTATCTTTTAACTATCTTAGACTGATAACGTGTGGGCCGATAGTATCTAAGAGCTGTGAGGCTTGTGGACCACTTAAGCTATCGACTCCCATTGGGGCAAGTGATTACCCGGGTGCTATCCACAAGACCGCACTTGTGTCCTTGCGTCGAATTAAGAAAGCTATAGGGACCAGCTGATATTAGGTGCTGAGGAGTGCTACCGGCCTGTTTCACATATATCAGAACGCGTGCCCTGAACTAAGACTCAGCCAATCAATACTGCGTTGTGGGTGAGGCAAGTATTCTGTCCGGGGATGCTGTGGGGGACAGTATTGATCTATCATACTAACCATAGTCGACATCTCAGGTTTTCGAGCGCTGACGGTACAGACAAATTTAGGGCGCTACGAGAACAGCATGTCGCTTGAACCGACTCAGGCGCCGTAATTAAAGGGAGTGTGCCATGAACTCGAACGCACTCCGTATCAACGCAGAAACCGCCTTACAACACTGAGCGGCGTAAGAATACTCACTCGATATTGATTACCGTAAGGCTATATTTGTATGGGAAGCAAACGAATGACATTTCCTGGATATACAACAGTTAGCTGAAGGCATATGTGATCTGCCAGATTCCAGAAGCTGATGGGGGATCAGGATGAACCTTGTCAAGGATTCGTATCTGCGCTATACAGGGAGAACTGTGCGATTGTTGAGGCTACGCCGCGTAGCCGAGCCGTTGGAATAAGCAGCCCCGTATGTGGACATTGGTAGGAGCATATTCAACGGGCCACTAAAGGTCGCAATTGCCTACATCAGATGAAAGGTTGTTACCGGGCTAATATCATATAGAGCCCTCTAATATCCACCTGTTGTATGAATACTGTCGCAGTTTCATCACGGTTGCCCCTAAAACACTGACAATTAGGTAGCGGTATCGTTTCTCATCTACTCAAGGCGTATCTTGGGTCGCAGGGGCACGCCGTGGTTGCTCGCCAGTTACTTACTGACGGTACCTCTCATTCTTTGCAATGCGGGTACTTGTGTCGTTGAAAGTAGTGGTACTCGCACCAACTCAATCTATCGCCGCTGCGAGACAGTCCCCGAAAGCCTCCGCAGGAGCAGCGCTACCTCATATCCTGCACGATTAGAATTAACTGCCTCTCTAGAAACGAGTCTTACTAGTAGTTGACCTTGATTCTACGGCCACTCGCATCGCGATGATTGAGAGAGTTCCCCCACTCACGAATTAGGAATCATGTTGTAACAGCGGTCCCACTTGAAGGTGAGTCTCCATACAACGAGTACATACTTGAGCAAGCAACTAGATTATCAAGAACACGCATTTGTCCTAGCCTGAACCACTTTTGGTCTCACATAAGACAGCGGGAGAAGCGATTCGGGCGACGAGGCTGTTAAGTCGCACGGGTTGCTATTCATATAACACCTCGCCGTCGTGTTAATGATGTTTATGAGCCCTGGCGGTATGCAGAGCTAATTGGTTTGCATGGGTGAGGTAACTTGATTCCGTGTTTGGTAACGAGCGGCGGTCTACACCTAGTCTCGGCCATTGGAGACTGTTCGCGGGGGTAAAAAATCAATTATACAGACACTCTAGCCTGATATTGCCCAATTTGAAAGAGTTCAACCTTTCGCAGTTTAGTGAAAACTGAGCGGTTTGTGAATATTACCGGCCTTATATATCAAATGGTCCGGTACCAAGCCTAGACATGTTCGGACTTTGTTCCGTTAAAACCGAAGATTACGCATTTCACGACTCTAATTTTTAGAGACTGCTAGACAGGATATCAGCCACGGTGCGTCCTTCCTGTATCGCTACGTACTTGCTCCTCGCCTTCTATATAACGGTACTGGCGAATTCGACAATACCCTAATAGGAGCTGCGACTCTCTAGACGACCAGCATGCAGCTTATTTAAGTCACACAGATCGTAAGAGAGCCTCGCAATGCTCAGGATATCGGCTGCCCTAGAGGATTAGCGGGAGTTGGCTGGCGCTATTGAATGTGTCAGCAATGGCAGCTCCAGGATCGTCCAAGGAGCCGCTGGCCCGTCCCATATGGTCTTCGTATCAGTACTGATCAAAAGGCGCAGCGTGAATACGTTTTCCTCCATAACATCCAGTCAGTAGCTGATAACGTTCTCACCCACTGACTTCCAACAGGGGCGATGGACCTCCAGGCGAGCCATGGAGTTCGACCCCCTTGAGGTATAGTGTAGGAACGGGATAGGGATTAAAAGCGTTGTGGTTTACTCTAAGCAGGCTAAGAGGCATAATGTCAGCCCATCAGCGCGCGGTTAGACCTAGCCGATTGGCGCGTACCAGGAAGCCGTCCGTCAATTTACAATTGGTCGTAGTCGGGATACCATCTTGAAATGCGTAGTCCGTCGCGCTTCGGGGCGGGCTTGAAGTGATCATGTGCACCCTTTAAAGCCATAGCCATACAACGTACCTCGGCTGAGTAGGTTCATTCTCTTGGAAAAATACCGCTAAGATAGAGACACCTAAAGTAGGCTTCTTAATAGGGCATGTGTTTCCGCCTAGCGTTGACAGCATGTGATTAACCACTTGACCATCTGTCACGCGTCATGCTGAAGCTTACCCTTGATACACGGGCCGTTATCCAGACGCCTGGAAACTCGAATTCATCAAAATTCCTCCATTTCTCTGGCCCGACAATCCACTGTAGAGTGGGATCGGTGTAATACCCTGAGTTTTCTAAACGGCGACACCGATGCTATTTAGTATGCCACGCGCTTCGTACTGTTGAAAAGCAATTGGAACTGGATGTCTATCCCGTACTTTTAAGTCGTAGATCCGCATCATCCATGCTAATCGTCGTCATTAACCAATCACAGTCTTGCAAAACTCACACTGGCTGATTCTGTCCAGCGTTACCGCGGTCCTGTCCGATTAAGAGCTCTCTCTGCCTATTTTCAGTTCCCTCCAGGCGTAAGGGACTTGATGTACACGCTCGACGAGTGCGGCTCTCTGTGACTAGAAGTCACTCGGGCTAAAGACGACTAGAGGTTTTTTCTGCGATCTAATATTAACCATACCCTACACAAACGCCCACCGGTTTTTATCACAACCACAGTAGCGGAGACGTAAATCGTTGTGCACAGAAAGTTAGGTAAGTTATCAAAGGGCAAAAGAATTACAGGCCATATTCTTTCAGTGTGACCTTCGAGTGCGGATTAAGTCCGCGGCAAAAGCCTAGGGACGACATCTTAGTAGGCTATCTCCACCCAGTATCTGGCGCGACGTCAGGTGTCAGTACCATGCTCTTATGCCCCCCTTTAGGTCCACCTAAACCTCGAGGTCAGCGATTGACCCATGTAGATACTGGTAGACGTCGGTGCCACTATGATCGGTTTTGTCGTAATTCACGAGCATTTGTCATACTGTTAAAAACAAACTTTGACGACAGTTTGGTGCTAATTTGAGAACCCACGTGGGGCCTGCCGCCGGATGTACGGTATGATCTCACCGGGTCTCCATGATACCCCCATCAGCCTCATGTTCTGGCCCGTCCTCAGAAGCGAGCCCTCAGTCCTTTCTTAATCTCCAGTTACTTATCAGGGAGTCCAGAAGCTCCGGGTCTTCCAAATCCTCCGCGATGTCTTAGTCGACCCTAGGGACACCTAGAGGATAGTCGCATTTGTAGTGTAGCTGTCCGAGAGCAGAACGCTGCGGCAGGCGGACATTGAAGTTACGGCTATGTTATCAGTCATCCTCGGCTTATAAGAGGCTTTGGGAAAGTTGGGTTAGTGGCCCAAACGATGATATGCACCAACCAAACTCTTTCACAGCAATCCCGCAGAATAATTGCGGCGCGGACGGGCGATGGGCCAGCTGCTAGGGTAGCGACAAAAGGACCACCAGCTTCTGTCTGAAGACAGGGGCCACCAAACCACCCTTGTCCAACTCGTATGCCCGAACAAGAATCGAGATCGAATTGTCACTTATCATCCCGTACACAGTAGGTCCCGTCTACGTATTCCATGCGTTGCCGCAGGATTTACACCAAGTTTGGTCGCCGGTCCTCACTCGCTAACTACAGCTGTGTAAAGCGCGGGCGAGGGCGATGGATACGTACCCGAGGTTATCAGGCTGAATTGCTGGTGAACACTTAGGTACGACTCATACGCGGGAACCCGGCAGAACTGTACATTCGCGGTTTTTGTCCTCTAGCTATTTCCAAGAGCTGATCACGAGAAGTCTCTCCACGCACATCGCTGAAGCGAGACCCTCGCCAAGTGTTACTTATAGACTTCTATGCGGCGCCGCAGTTTATACAAGTCCTCGCTCATTTTAGTTCGTGCCTACACTGTCACTCCTACGGTACGCCACGGCGCGTGGTGATGAAAAGGTTTCAAGTTCGTATGCGAAAATACAGGCCATTTAACACGGACTCCGCGTCCGGGCGGGGCCGTAACGTTGCCCGTACCCGGACAGTTCCATTGTGAAGCACTACAGCTTCAATGTTACCAGTGTAACGCCAGCATCAAGAGTTGCAATGGTCTAAGCGTCACCTGAATTTGCTATATCCTGACGAGACAGGCGTGCCCCATCGGAATGGCAGAGGTAATAGGCAGCATCCCCGCGGATCTTCATCTGCCGTCAACAGCGCCGGATTTGTAGGCGGGGCGATAAGCACTCGGGGGTCATCGTTTAACCACCAAATGGGCAGTACAGGTGTTCTCCTGTCGGGCCGTGTAGTTAGTCCGACAGGTGAAACAATCTGTCAACGAATTGGCGCCTACTTGGTCCGCCAAGTGAGATCTTGAAATTACAAGTCTTTCCGGCGCAATCAGGCCACGATACTGGGGCAACACCCCGTTGGGACGACTGGTAGAAGCTGGACTCCGGGACGGGGCACAAGGCGGTGGCGGCATTGAACAAGCACGCACGCTCCTCCCTATACCTACGACAACTTAATCTTGTACCAGACAACCTAGGAACCCTCACTTGACTGCTCAAGCCGAAGGGAACAACCCCCTCCTTGGACAAAGCTTACTGCCAAGGCTTGGTACGTTCGCGTGTCCGTTCTGTATCGGGACCTGAATTGCGTGTGCAAGCGTCATTCGCCATGGCCACTACGGCCTGGTCGGGCACCCAGTGTGATAGTCTTTCATGCGAATGGCCCAGTGCTATCTTGTTCGCAACGTTCTGTAGATAGAAGGCCGTGGAAACTGCGACTATCCGCCGCACAACCTTCACGGGCCCCGCCTCTCTATGGAATACGTGTCTCATGTGCGATATGAAGGTTGCCCTCCATAAAGCAGATAGTGCTGATGTGCACTACTTGGTACTTTGAAACGTATTAGTCTCACCTGCTGATGATTCCTTTAAAGCGGTGCAAACAGCCTTCGGCAACCGGCCACTTAGGCTCGACGGACACCATGCCTTTCTGACTTACAAAATGACCACGCCCCTACGACAGCTGTCGTTACCAGGCATGCCTTAGCTGTCAATGGCCTCATCCTGCCTCCTAAGGGGGTATGTTCTCCTAGTAGCCATGTCATAAAACCCCTGCGCGAACCGGGTTATCTACGAACAGTACGAACCCGGCGCGTTTTGGCTAAAGTGGGGTTTATTCAGGGAGCCCGACATACCACAACAGTAACAATAACACACTAGCCGTTAGCAGGGTCGACGTGCTCCCGTTCGCGGAATTCTGGCTGAACGTAAATACGCACCTGAGCGAATTTTCCACGAACACTTTTACATTTAACCTCGCAAGAACCCTCCCCATTAACGAGCTGAAACGCTTATAAGAGAGACGTAATGGATCAGAGACCATCTCCTCCGAGAAAAGTCTGGGTGAATCTACGATGGGTATCTGGAACCATGCTCCCTCTTCCGGAGGACAAGCCCTTAATATGGAATCCAGACTAAAGCCATAGCGATAGCAGCTTAAAACTAAGGCACGTCGTCCAGCCAATTCGGCCGATTCCGTTTGGAACAAATAGCTGTCTGTCGCAAACACGACCCTGGGAAATGATCCAGTTCTACCGCACCAGAAGCGACCCACCCCGTATTCGCGTGGTGTTCCTTCAAAAACGCCCCCTTGGGACTCAAGACGTCGAACTTCTTTACCCCAACCGTTGCGGGGTGTGTGAGAAACCGCAGACTTGAGAGCCCGAGTATCTAATGCAATCTTCTCGGGTAACAAGTGTGTGTACATCGTGACAAGTCCTTGGGGTCTGCAACAGTATGTCCGACCAATTGACCGACCGCAGCATAGTCACAGTCGGAACTTTCGGAGTAAATCCAGGAGGGACGCCTATAAACTGTTCATAGGTGTCAAAACGGGCAAGGAACCAGAGAATGATTCAGTGCATTCGAAGAGTGGACGCGGTAACGACGTATAAATTTCGCGCTTCCAAGTAACACCGGACCGCGATGTGTGTCGCATACCGAGTTCTATGACGATGCTCAGAACCTTTGTCCACTAGCTTGCAGTTGCTCGACCCTAAGCGTTGATCCGATCTGTGTACAGAGAATCCACTTCTTATCTCCGTTGGCCATTAAAGCGTTTGTGTCCAGATCGGACTTGGTGTGTATGTAAGGCCTGATACCGCACAATAGGAAATATATCGGCTAAATTAAATTGGCTCGGGATAGCCGATCTCGAATACGTCCATTACTGAAGCAATTGGTTACGCGCGAGCCCCCGATATTGACTTTGATAGTATGTCCAAACGAGTACAAACTCGTTGCACTTAAGTTCGACTTGCTATGAAACATAGCCGTAGGAGGATTTAACCGAGCCACAGGCGGCTCCCTCTATCTTAGCGGATCGAAGTAATATTCTGTTGTCATGGCTTTAATTGGGAAATGGCTGCCGAAATTTGGCGAAAGATAACAAGTTAATAAGGACAATTCCTACTTACCAAGGGTACTGTTTCGCAGCGGCCGGTACCCCTTCGAGACTCTGTTGATTTTCCGTGTACACAGGCAAAATGCATTGTATATCCCGGATTGCTTGCTGCTCATTAGGACTTTACGACATTAAAAGCAGACCAATTTGACCCTGCTAACCATTAATCAAGGTAAGCTGCTCTTTCACGGAGAAAGCGCGTGTCTGACTGAGTATATCTAATAGAGTTAGCGTACAGTAGTGATTGGCATGCCATCGAGAGGCGACGTCCGTAGTCAACCTACACCGTTAGAGAACCCTTGTCCGTTGCGCTTCTTAATCTTTTGTCGAAGAGGAAGTACATGAAACAATCAGATTAGTCATTATGATACACATCGGTTGGGACACATAATCTTTGCGCTGCAATACCCTACAGTGGCTGAAAGAGTGGCGTTGCACGCGGACTAGGATTACAGCGTATGCCCAGGTTCTTCGTACGTTCCTATGGGGCTGTAACTTAGTATCAGACAAGCTTGCAGACCCGCGCCCGGGCACCGTGCTATCTGAGTGCATGCCGTCGGCGTAAATCGTGCAGTGATTCTCCTCCGCCAACGGCCCTGAACAGGGTTCGGTGCTACTACTGTGGCAGGGGGGCGGGGTGTATGTTACCACAGAAACTCCTCACGCGGCAGGGTTGACGGCCAGTATACGCTATGAAAGCCAACAATTGGAGTATGAATCCCTCACGAGGCTTAGCGATGCAGAAGCTCGCCTGTAGACTAGTCTTACTAAGTGAAGAAACGGCGGACGAAATCGAACGTGGGTTATGCTTCGATAGTCAACCATGAGTGCATTCAGTAGAAGGTCGGAGAATCCACTAGTGTGCGGAATTATGGGTTCCATCTAAGGCGAGAAGGGTCCGGGTTAAGTCCAGCTTCTACACTCAGCAGGCAAACATACGTGGCCAGGCTCCTTTTAATCCCCGGAACAACCCACTCCGGGGGGTGATCCCGAAAGATAGATTTATGTTGAACAGGCAGTAGCGATTAAGGCAGCGGGAGTGGACATATATAGCAGCAAATTGTCTCCCTCGGGCCTTAGCTCTAGCTCCGGATAACATAACATACCTGTGCATTTGGCAGCAATGATGATCTTGTGCTAGGTTGACACTGGTTGGCGGACAACGCCCAGTAATGGGACTAGCCTGTGGCAGTTTGAGTTTATGCGTGAGCACAGAAGCGCGCCCGTCTTAGGTTGCTTCACACGGCCGATGTCACGGCAAATTGGTTTCCAGGGAGAGATTGACGTGTCTTGAGTCTACGCTCCGCGTTAAATACACCCCCCCTGACCACGTTATTGTGCGTTTAGACCTATTCAGTTCAAGGCGTATGGGAAGACAGCCCGGTAACGTCGCGGTCGATGTCGAGATCCGCTGCGCCCGTTCATAGACGACAGCATGAGAATCGACGGTCTTGAACGTTAACAGATCTCAAAGTCGTTAGCATAAAGCTCCTAGACCAGTCCGTATTGCCGAATGTCCTTAGACTGATAGGCTATGGCTGCAGACTCACGCATCAGCCCGGCGGGGCTTCAGCGATCTAAAGCTCGCTCCGAAGAAGCTCGGGATACTCATGAAGGGAACTTGAAGAGTTATATCGAGCACGGAGAGACCACACATAGCCCTCTATAGATTTGTAAAATTAATGGGATTGTCATACATGCCAATGGTATGGGCTAGAGGCGCCTGTCAGTCAAGGAGATAATTCGTACTCCCTTACTTCAGGGTAGATCATGACAGTTCAGGTGAGGTCATCTAAGGAAGGTCGCTCGGCTGTAGGGGTCTCGTACTATTAGCCCACCTCAGCCCATCCGCCTTCACTCACATATTGTCCCCCTGGCCTAATGGAATGGAAGGTGATCACTCTGGTCGGGTACTACCACCATATAAACACTGTCGCTGTAATTGTGTTCACTAAATACGCAGTCGAACGTCCCCAGTCCACGTCCGGGTGATGCCGCGCTCCCAAGTGGAAGGTATCGATTTAGGAACCATCGATGCTAAAGACTGTATCCTCGTACGCAAGCTACCGGGAGACACCTCCGGGAGCAGTGTCGGTACGCTTGTATAACATCCTGACAAACGCGTTAGTTGAACATTAGGCGTGGTTCGCAAGGTCGGCACTCGCTGAGACAGTGTAAAGTTTGGCGGCTCGTTACCATGAGGCCTTTTCTTCTTGGGAGGTGTTAACCCAGGGCGTGTGCGTATACGCCATAGGACTTACTAAGTTGTGGACACCCGCCCGCCTTTTTAGTTTTAATAATGCCCGGCACCTTTGCTTATGCGATTGCAACATCGCTGCAATAAGCTCGCTGGACGTATCAGGCCGGAGAGATGCTATCGCGAAAGGATTCTTCCCTCGCAGCGCGTTCGCATTCTCATTTCGATAGAGCTCGATTAAATCACGGAACGCTATGGAACAAGTGTGCGGGACCGAGAGCAAAACGCACGTGTTAGCACCTTGACCTAAGAATTGGGGATAAGGATAGCCGAATGAATGCACTTAGATGCGTTTCGCCGCCTGCTACCACATGAGCTGAGACAATTAAGCGCAGAGATCATTGGTGCTGTCAGTGCAATACCTATGTGGGCCGCCTTACACTAATTAGACATCCGCAGCCGCCCATTTGCGGCACGAAGGGAAATCCGTTAAACACGGGCCGTCCGAAGTCCACAAGCACAGGTCCGTGACCCGTGATGGTTCTGTTTTAAGCCATCTTTTGGCGTTCTGTCGATGAAATGCTGAGGTTAAGTGCGCGAAGTTGCTTTCCGACGAGACTGCTCCCTGCCGGCGGGTACGCGTACAGACCCTGCGGTCCGCGGGCGTGATCTAGATTACAATCGACTTCCACGGCTATCATCCGCTCGTTTGCCATGGAGTCGTGACAACCAGTCTAATTGGGCTATATCCCCTGCGCGAGTACTCCGCGGCCATAGGTATGCGTTACAGCGTTCCGGAGCAAAGCGTGCACTAGTATCTTCATCCATGAGGTAGACGATAGGGGTGGGATCGACTCCGATGCTAATGTCTAAAGTCCCCACGCATCTATGTCCCATAACACATGACCTACAGACCTTCTGTTGTTAAGATGGTGTTTGTCCGATGAATCGTAAAGACTAGCTGACTGTACGCAAAACTAGGTAGTTTGCTATCTGACCATGGGGTTTGTCTCTGTCGCTTTCGAGGGAATAATTAAAATCCGGGATGCGGGTTTCAGGCCCACGTAAGGCATCCGACTATCTACCAGCATACACGAAATTCTAATGAGTTCAGATGCCGTCTAAACAGCTGATAGTGACTGCCATCCTAGAGGACTCGCTCTCTTCTTACCCATGAGGTACTGCGTCGGAGTTTACTGACCACCCCCGATCCAGCTAGAGCGATGAAAATTAAGTTTTACGGACCATAGATGGGGTGTATACATTTACAGCAAACAATCGCCCTTGCTCCTAGAGTTACATACACGCCTCTACGACCTGCCAGCCAGATCTCGTTATCGCCCAAGGCAAAACTTACCGCAACGCGAGGCGCCTTTGGGACGGCTGCCTCATATAGCCGCCATACACATGACTACCCAGCGACGTTTGTAGAAGCAATGGGCGAAGAAGGACGATTCGAACACTATCAGGGGTGCTTCAGTTTACCTGGAAACGACTTTCTCTGCGATCCTATTCACGTCCTAAAGCATCTCCGCTAACTCGACGTTGAGATGAGCCATTGGGCTGGAACAACAGTCAGCCCCTAATGAGGCTACCTCGACCAGTTTTGGTTGCAAAAATCCGCCCCCGGCTCTCCTTACAATTTGCGGTCGCTTAGAGACATCATTATTCACGGTCGCCAGGATACTATCCGTACGAGACCTATGCGTAGATTTAAGACCCGGCATTCGTTTTTCCGGTGTATAATGATTCAGTTATTACCATCCACATCTAACATCAAGAAAACCAGCAGGCGTGATCATGCTTTAGGTGGGTCCAGAGGATGACGACAGGCTCTTGCTTATATCCGTTCACTACTGAGGTCCCGGGGACCCACATAAGGAGCATTGGGCAAAATACGATTGCAGAAGGCCGCAGCTGTGCTACCAATTCTTGCCTTCCGTGTTTCCCTATCACTAAGACACCGCAAAGTCCATCAGGTCGAGTCATCCCCAGCCGGCAAGCAGATTCAGGTAACTACACAACCTCACTGAGCAGCGACGGCTTATAAAAGTGCGTTTGTTAACTTAGGTCTTTAGCTATAACACGTGGCTGATCACACTCATTCATGTATCATCGGCGCTAATGCGGCAAGTGGGAAGACATCTAACCGAGGGTAAGAGTTCTATCTTAGATCCGGTATCGTCAATACTGACGCGAAGTTGCGGACCATTGGAGTGCGCGCCCTCTGGCTGTTTGGGGTATTTCATCTCTGAACATTTAAACATGTAAGAGGTTGAACGATCATGACTCCAACCACCTTCGCCCAATTCGAACAAGTTGACGGCTGTGTGAGACCCGCTCATAATACCAATAAAGAAGGTCACAAAGCTTAGTGCACGTTTGATGTGAGCCCAGCCCGCTAGAGGCCTGCTAAAACCTGCAGCTGACAGGGGCGCCAAGACGCGAATCTGTTGTATTACAAATCAAAGAAACCGACACATTTTAGACTACGAGCCAATTACGATATCGGGCCCCCTTCCCGCCGAAGAGTTTGTCAGTCACATAATGATCGTATGTCACCGATACCCCTGGAGGGTCCAAATATAAAGAACAGTCATTTGTAATCTGGGAAGTCACAACATTTATGACAGGAGATAAGGTTATACAGCCTTGTAAGACTCGGATGATAATATTCGCTCTATTGACTGGCAAGTATTGCACTATTTGCGAATTAAGAAACACCCGCGTCCCAGCTCGACATTCCCGAGTGTTCATTCCTGGTCCCATCTTGACCGGGTATGGACTGGGTCCCTCGATGAGCACCTGTTCGCTATCATGTGGGCCGATACATCACACACCCTGATCAGGGGAGTGCCGAATTTGCACCGTCCCTGTGGCATGAAGTCTGGTGCACCGGTTACAGGGATAGCCATTGAATTCAGGGCCTCAATGTAACCAGTAAGAGCAGTGGGAAAATGCTGATGAGTTCGGATGTGGTTGTAGTCGACAGAGTACCGCGCATACTGCTTCTTGAAACGTCCGCGAGGGGATATTCGGCTTGTCGGATTATGGAATGGGATCTCATAAATCTTGAACAACGAAACACTACATGCGTCCCGACCGTGCCAAGTCATCTATTTAGAGTGCGCTTAATATATCGTAAGTAAGTCTGCAACTGTTCCGGCCGTACTTCTTTGTGGTTCCTCACAAGTATGAACCTTGTGCTCTATTCCACCGGAAGCTGGTGACTGCAATCAGAAATCGACCTGTTCTCGTTGACTGCACCGGCTGACGCTTTCATACTCTTATACGGACGAATGAATTTCTAGTTAAAGCCGCGACTTTTTAGGAACAGAGGCACCGGTTGTATCTTCGCCCGGAAATATTGGCAGCTTTTGTTGCGTAGTTATGGCCATACTAATACCGCCTCATTAGTCTATATTGTTTGGGCACATATATCATCACGCGTACCCGCCCAGTACTAACCATCAATGGCCTCTACGAGACAGTAACATTTTAAGACCCTTAGGCGACTCAAGAACTTCTCAGCAGGGTTCTCGCGAGATCATAATCTATTGCGGTTTCGTTAGCCATAGCAGCATCTTGTATTGTTATCATGTCAGGTATGCGCTCTTGTGAGTCTGACGAGTGGTCTTGTTAGTCGTTTCCACCGCTCGATGCGAGTGAGTGCAGACCGCTTCATGTTCTTCGGTTGCTCGGAATGGAATGGGGCACGCAGGCGACAGCCTACCGTCCTGCCTGGCGAGGGAAGATTTCAAAGTCGCTACCCGATCTGGGTTGTTTCTTAGTCGGCATATTGGAGGCGACTCATAGAACGTTACTTCAAACATGGGATTTCATAGTTGTTTTAGAGCCGCAAGTCTTACCACACGATTGCATAACTTGATCGTATTGCGAAGTTTGAGTCCGGGAAAAACAAACCTCTAATGATAACACATGTCTGCCGGACCGCCTTGCAGTTATCACCGATCCGGTTCATAGGGTAGCCAGCTTCGTATGACCTTAGCCGATTACTGTAGAGGCAATTGCAAAGTCAAAGCGAAATTCAGGCGTACCTCAGACATAAACGGGAACCTCGTCAGCAAGATCGGTAGACCTAGGCTACTCACGCAACGCGGTATATGCCCGGTTACTACGCGACCACGTGATGTAACCTGCTGTGTTTTACCTGGATTGCCATCGCTGGCAGATAAGTATACTAGTGATCGTGTATTCAGCATTAGGTTATTTAGAGAGAACCATCCACGTCAGGTTATTGTTGTTAACATCGTGTCGGGCTCCATCAGAGATATCCGATCTACCCTGTCAAACAACGCGAACACGAGACAACTTTTTGCGGCGCCATTTGGCCGCCAGCCGCAGGCCCCCAACGTGGTCTTACCATGAAGGGGAAGCACTTGGACGTGAAAACTGAGGTCGATTTAAGTTTGACATACAGGACTCTACGATGACCGTCGGGTGACCAATAAGGATCTACATCTCTATTCTTCGTAAGCACTGATGGTAGTATTCCAGTAATGGGAAGCTCGCAGCCACTTTGATGCTCGTTTGATAAACCCATATCGACCAAGAGCCGGCGGAGTGGCGGTTTGCTTATCAAATTCATACAGCCTGAATTTGGTTATCAGATGCCTAGCCCCTGAAACTGCAGCTCAAGCCACTGACTACAGAACTGCCCGTTTCGCCGACATCAACCCAATCGAAAGCACGATGAATCTATCGGTAAACTCATCTGTGGATCCAAACAGCATCGTTGGCCAGTACGATTTTTGCATCCCCTAGGACAGGCGGGTCCCTAGTCCGCTTGGGGCCACAGCTTGAAGGATTAGAACAAGTCGTGAGGATAGTGTTCTGTACTTTACTATAAGTATTTCGAAACTATCCATCCGTTGAGTTGACTCACGTTCGCCATGGGTTGAAGATGGACCTTCAATGGTCCAGTGTGCGCAAACAACCAGTAAACGTATTATCGTATCGAGGCAAGCGACTCATCACGAGCGCCTCGTTGGGATCGCAGAAGGGACGTAGCTGGTCACCCCAGCTATTAGGCCTGCATTGACTGCCCGCGTCATAATTCGTGCGACAGTCTATCCCGGTACTCAGCTCTACGTTATGTCTACTAGATACTCGGCTCTTGAACACCTTCCGGGCAGGACCGGAATCCCTGTTCCAGTGCACGATAAGAAGAGTTTTCGCTTCACTGCAATAAGCCGTCGATTACACAGTGAATGTAAAAAGAATGCTGGCCATGAAAGCATTGTACAACCATGCCCAGGAGGGTCTCGGACTCTCTTTCGGACAACCGCACTGGCCTTTAGAGCTGGAGCGCGGGTAAATTTCGAGGGGGTCGACTTTTTCGGGTGATTCCATATAGGCGATGTGAGACACGGAACATAATCTGTCACGATGGATGTGCCCCATGACGACCGTTGACGTACGACAACTCGAATTCAAGGAGAGTAACGAAGCGTCCGATATAAAGTCCCAACGTCTTCCGAGATCAGACCCAACTAGAGGATAATATTGTGCCAATAAAGACAGGCAAGCACTGTGGGGTCGTCAGTTTTGAGCCTAGCGTATCGGCAGAAGCTCGCAAATAAAGTCACTGACGCACATCGGGTAACGTGGTGTCCCACTGGATTTAGCATTGCAAACGGCTCAGAGCGCGGGATATCGGTGTTCTCGACTCCGAATGTATTGAGTGCGCCGAGTCGCCTCGTTATTCCGGCTTGAGTCGCTCTCTTCTGGGATATGAGAGAATGCTTTCAGCCTCTGACATCCGCCGCGCATGAGAGAGAGATGGAGATAATAGGGTGTTGGCATTCGGGAAGGGCGCTCAATGCCTACCTCGTTCCCCTCATGGTTCCCGCCTTAACTTGAGGAAAGATGGCCAGTGTACTCGGACCCCCATGGAAGATTGGTTTCCATAGATTCCAGCAGACCTAAACGCTATCTGTTCTAGCACGTAGGTCGGAAAAATAACGGCCGTAATTGGTTTTTTTCCCAATATTACAGCCCTTCCAGAATTACATATCGTCACCAACTAGGAATACAAAATCGAGCCAGATTCCCAAGCGCTCCCATATCTTTATGGTGCATTGATATAGCCAAACCCTGGTAGAGAAAGGGTGGGCGTACATCGTCAACTCTTCTGAGTAAAGTCTCAATTGAAGTGTCTTACAAAACGATCCGATATCGACTAGCTGTCTCTGTTCCTTCGGTGCCCAATAGACATTGACAAGCTGTGAAATGTTGGTTGCACTAACTTTGGGAAGCTGCTACAAATGGCATAACGATTACGACCGACGGGCTCTATTCCCTTTTGCCCCATCCTACTCTGTTATCTCGCAAATCCCAGATGTGCGACCTCCTAAACAGACAGAGTGGTGTTCCCGCGATCTGCTAGAAGCAGAGTGGTCTGGGTACGACGTACCTTCCTCGCGGAAAGTTAACGGGAGGGTTACCCTCCTGATTAAGCTCCGCGCCCTCCATCACGACTCCGATGGCCCGTTCAAACGACCCACTCGATATAACAGGACTAAGCCACCGCGCAGGGACCGCTTGACCTATCGCCAGCCCGTTGCTGGGGGAGCCTTGCTTTGCAAAATTAAGCCCCGAACCGGACATTTGCGGTCATTGCAAGGGCAGATCTACTCGTAAAGTTTCCCAGTATCGAATAGCTACGAGTAAACGGAAGCATAAACGCATCAGTTATTCCGGGAAGCTCTCTTTAACGTTGCTATCTCGGTATTAAACTCATTTTTGCCTCCGTCACTTGACCCCACCGGAGACAAAAGGAAGCGCGCTCTAGGCGAGGTATCTACTCGTAACCGCATCCACCCGAGCGTGGGTATTTGGCCTTGGTAAGGAATCTATCGATCATCTGACACGCTACTCCGGCTCTAAATAGCTTCGTTACGGGGACTATTCACAAATCACTGGAACCCATCTTTGTAAAATTGGGGGGCTGGGGCCATACTCAGTAACTAGGCGGTTTCGTTATCCACAGTAAGCTAGCTTGCCCCTTCAGTACAAGATTCAGCACTCTATGTCTCATTGCGGGTGCGGTCCTGAATGACTGTATTTCTCCAAAAGTCCTCTGAAGCGTCATCATCGTCAAGCTCCTTATCCTCTCTAATTGTCAATATTCAGATGTTGCGTCCATCGGAGCTCGGTATGGCGTGATAATACCAGAAACGTGTTAAATGAATGCTGACGGAAGCCGTTCGACCATTCCCCGAGAGTGCATGGTCGTGTGGCGACAGATCCTTCATTTACGCTACACTTTTGGCGGTTAGACCTCACCTTCCAGGTGTGTCGTGCGCATCATTCGGCGCAAATGACAGGTTTTGCCGACTTGACGCCCTATCCGTGGCACCCCCCTACCTTCGTGAGCGTTGGCCCTGCGGCACTTCCCCAAACCCTGTACATCGTGGGAGATCAGAGACACTCATAAGTACTAGCGTTGGAAGAACCGGTGTTGGCGGGTGTCAGCTCTCTCTGTATCACATACTCTGAAGTCCTACCAAGAGGGACGCTGCCTACGCTACGCCCAGGTAAAGGCATTGGACTGCTTGTTTTGTTCGGCGTCGCCCATTCACTACATCGTACCCAACGGTCTAAATTGTTGGACCAATTTGTTCCACGGATGGGCGAGCTGCATCACCTCACAGCGGAACCCCTTCATAATTCGCGACCTTCCCGCAAGGTGAGGTATAAGGAAAAAACGGCATCCCGTGCAGTCGCGGACCGCCACTGGACAGGTTCTGAGTACTAGATGGGTGTGGCCGAGAAGATCCGGACTAAAAGTCGCCTCAATCATCCGTTACCAGTTTCTAAGTGTATACGTGAGCGACACATTAGCTCTGGGTTTCACCACCAGTCGAATGCGTCAATTCAAAATTGGCGTCCTCGAACACGCTTTACGAGCGATGCTCATCGCGACACTCCAGTCACTGTTAAAGGTGTTCCGTTAAGGCAAGAGCAGCTCCACATATAACGTCCATGACATGTTGCAAGCCTGCACCATACGTCCTTTTGGAGCCGTAACCTTTTCCGGAAAGAGGATTCAGGTCAGCATTTTAGGTCTCTATTAGTGACATTGCGGATTCGCTCCGTTAACTCAAGGCCATCATTTTGGGCACTCCTCGGAGGGACCTAATTTTACTCCTACTTGCGCGATATCGATTGACAAAAGGAATTGCGTCGTATTTTCCATTGATATAAAGTGTACTTACGGCCCTGACATATCCTCACGGACACGCCAACACCACCCCGCCGTTCACGTGCCCCCCCTCGGGCTACCAACTGCACAAGGGCACCACAGCTTGACATCCATCAGCATGTTTTTTCGACTATTCGGCCGGCACCAAGTTGACACCGCCGACTGACGCGTGGTCAGCCGATCAGAGGCACCAAAACGGGGTCGCATGCCTTAGACGAATAAGGGTGCCATCGATGTTGGGTATTATTACCGAAACATTCGGATTAATAGTTGAAATAAACCTCCTATTCCAGAGTACTTACCCTAGACCTCAAATAAGACCTGCGAGTGGATGGTCTTAACAATCGGGTGGTCGTGGTCCCGGTTTGGGATAGCGAAGGATAGGGCAAGAGGACGTCCAAGTCCAGTAAACTCCAAACAGCACGCTCACTCTAACAGGGCGGTGATAATGGGGTAGTTAGACGAGCACTCATCGAGCAGTACTTGCAACTGTCTTTCTCCAAGCGACGCTTGTCCCAATGGCATCCGTAGACGACGATGTGTCGGTCCGCCGTCAGGGGAATTATTCGTATGATGCCTCGAGTCGGTCTCGGGAACTTTTCTCGGTTTCCGGTTCCTAGGGTTGCATCCCTAGGTCCAATAATCATCTGTCGTGAAGGGGCGAGTCCTTCGGGGAGATGCTAATTTCTATTGGCCCCAACCAATTTTATGAAGTGTCGGGCGGCGATGTAGTAAAATTTATTTCTATACCATGAAGAGTGCTCAAAGACTGATCCAGGTTCTGTCAAGCTTTTTCTACTATCTATGAGACCCTAGCCCACTATGCACTGGATACGATAACGATGCTAAGGACTACGATGATGCGTGCGGGTATTTACGCTTTGTTGGTTACCATAACACCCACAACGGATCTCTTATGGTTCTTTGATACTTTAAGATCCTTACAATATATCAGACATGTCTACAAGCCCATTCGGTGAATTCTTTTCTCTCTGAAGAGGGTTTTGGCGTTCAACCGGGTATGCTGAAAAGCGACTAAAGTTAGCGCGAGAAACATTATAACACAAGCTCGCTGTCTTAGCAGGTCGGGCTATGCCCAGGAGGGGAACGATGATGGACACGTGTACTTGTGCGACCGGTCATGGACATATCTCTCCGTTGGAGCGTCCGTTCCCAAATGGAGAGAGACTGTGACAGTTATCTACAACTGCCGGTAGCCGTGCCCACTCCTACGGTACCGCTAGTCACAGGGATAGCAGGAAGTTAGTCCCAGTTAGCCATCACGCGGAAGTTATTGACCGTCTGAGTTATTGTTCCCATTATGAGCCTAGCTGAGATGAGTCTCAGCGCGGCTCCGCCTGTTGATTAAAATGTTTCCAGATTAGGTACTTCCATGAACTGATTTGCTCATACATTGACGGCGGGCGAGATGACTACGCTTGCCGACTACGTGGGCTCGGCTCACAAGCTGCGCGGAGTGATCGAAATCAAGTCAGTTGCACATAGCCTCACCCAGCACCCTTGACCGGAGCAAAAGTGCTGAATGACTGCCCGCGCAACAGCTCATGTCTAACTATAGGTCCAAGGAGACAACTTGGAGAACGTTCCTGCGCAATGCTCCCAAGGTAGCCATGTGCCAGGTAAACGCCTGCTAATCTAGTTAAGGTTACACACTAGAGGGGTCCCATTATTGCTCACGTGGGCCACGTGCTACACTTCGCCCATAGCGTACGGTCTTTCACTAGTTCCGGGTACCCACATTACGTACGTTCGTTCACTACTCGCTCAGTAGCTAAGATCGGGCTCTGGGGAGTTCCAATAGAGCCAGGTCCGAGCCATCAATTGTCTGACATATTTTAACTCTAGAACTAAAGCAGCCCAGGTGGGAAGGCCACAAAGGAGCAGCCGGAGACTATCAGATAAATACATACGCACCACTAGTCGTCATAAATAAAGGAGTTGTCCCCATGCTACTTAGGATTCAACGGCTGGTAACGGGACGACAAATAGGATTACGGTTCTGTCTTAGTAAGGCTTATTCTATGGAATGGGGACGTTGGGCCTTCAAGAACGTAAGGGAATGTCAAGTCCGGCTTGGTTTTTTCCTGATAGGCGTGATACGCGAGCTTTTGAGTGTAATAGCGGGAGTGTCTGTTGTTAGATTACTTTTTCCGTAGTATCTCACTCAAACTAAATTAACACCAGTAGGTATTATACGCGGAATCTTCCGCTTTTGACGTAGAGCATCCCGTGTCCAAACCGAATTGTCCTTTTTGGATCGCATGACATAAGGTTAAGAATTTACCACCACTCGTAGGGAAAGACCAAAGCGGGACAGACAACTGCCAGCGGGGCATAGCCTACTTCCTGTTATATCAAGCTCCAGCTGACTCAGAACCAGAGTCAGTAACGCCTATCTCTGACCTTTGGGTACTCCCACGCGGTATCATTGGCGACCAGCTTGTGGAGGATCCATTTAGCCACTCAACTTGTTTCTAGTAGAATTGAATAGACACTGGAGAGATGGCCAGCGACTGATCTTGTCATACACTTGTAGGTACTGTACCTAAGGTGGTTCAATCCTGGCTACGGGTAACAGTTGGTGAGGTGGGCCCTTCCTTGCGTTTGATGGGGGCAGCCTCGTTGGGACCGACTACCTAACCAGGTATGGTTTCCTCGCAAAGCATGGGCCGCCAGTATCAACTTGAATTCCCGGATTACGTAGCAGATTACTCCTGTAGTTCTTACACGCCCTCCTCTAGAGAGGAGCCGCCACATAGGGTACGCTCGTCCTGGGGATATTCACTATACGACTGTGTACTCCCTGGCACTGCGCAATAACCGGAAATAGGAACATGATAGCAAATCACAGGCATTGACCCCAGTGAACAATACCAACCTCAGAAAATGGGGGAACACCCTGCACCTCCGTGCTGCCTATAATACCTCATATCGTCGGCTCTCCATATGAGGGATAAAGATTCTTGTGCTTCGAATTTCAGACAGTCGACCAGTAGAGCAGAATAATAATCGTCGACCTGGTCAGTAAGGGGGCCGGCTAACGTAGACGTTCCCTCACGACCGCTCAACGTGTCTAGACAAGCACACAGCATATTCCGTCCGGATCCACCAGTGTATATTGGTAAGTTGCTCCCAACTGGTCAGGATGATCCTCGAAATTATTTTGGATAAATAGATACAATGCCTATCCACCCAGGTAACACCACTGGTACGCTATTTAACGCCTTCTCCCGGGTCGCTTAACTAAGTATGCTACACCCACATGCTTCAAATATGGTCGTTTCACCCTGTCGGTAGACTCGTCAGACCTTGTCTCATACCCAGTGATTTCAACCGACCAGTGGTGATATAGTAGACCCTGGCGGTAACGATGTATCCTTATTGACTCACCTCAACCCCCTGTTCACACACATTACGCCCCGTCCGGGGCGAGTAGTGCTGCCAGGATTTTGGGGATACAAAAGGTCTCTTCCTTAGCGGTGTAGGGGCGGATTTACCTGTTTCTCAGGTTAGAGTCACATAAGCTCTGAGATAGATATGAGGGCGTCATAGGTTCGCACCGGACATACCTCGCATGTCCCCCTGGCGTAGCCACAAGGTGACTAGAGCCCACCCTGTCCGCGACCTTATGGCCCACATCTCGCTACTCACACCATTGATGTAATAGGGGAGTTATCCTTCGTTCAAGTCCGTTACCAGGTTCATCAAACAAGCTTTACGGATTGAAGCATCCCGGTAAAGACAGTAGCATGACTCCAAGGGCATTTTATAGCCTTAAAGGGCGTCCATGCGGGCCGGCAAGCCACTAAACCTTCATCTCGGACTGTTGGTCCTCTTTGCAAATTCATGAATGCTTTATGCTGGGAGACTAAGAACTTTTGAGGTTTCTATAGTTCAGCGGTGCGACGAAGTGGTCAGGCGCTGTAAATGAATGGAATACTCCTAGCGGGTTACCCCAGGCTTGAGGTTTTCCTAATAAACCCACAGCGTGGATCTCACCCAAGGCGCTAAGCCATAAATCAAGTCCCTAAATGTCCTTTTTAGAGCAAATGATCAGATCTCTGCGCGAAATTTGATCAATGTAGGACCGCAAAACCGCGAAGTCCCGCTGCAATCAAAAGGCGTTATACCGCCACCATTCCCGTGTGCAAATATATAGGCGACACCGCTGCAAAGCTCGGCTCATGCGATCATAACCCCACGCATAGCTTCCTCAATGTTATTTGCACTTCCCCCATCACACTGATATGCCCGGATGAACACCATTCGGGGTTTAATAGCCAGAAGATCCGCCTGCCTAAGATAGATTGTGGTTTCACCGAAGTAATGCCAAGCCAGTAGGTGACAAGACTGTTATCCATTCACGGGTGTAATATTTGGCGGTTCTCCTACAGGGTCGTTCCATGTGCAATGGGCCCTCTTACGACCCCGAGCAGCCTGAAGTCTGTCGAATTAATCTTATTCCTCAGCCCGCGGTCAGGAGGGCCGTAGGTCATACAATCAAGTGAACTCTGGCAGCGTGACGGCAGAAATGCGTAAGAACAGGGCTGTAACGATCCATGCCGGGTCAAGAGAAGGCAAACGGGGCTCTAACGTCCGATCTCGACGAAAATCGGAGGAACCGTCGCTAAATCGCTGTGCGCATTATTTACTCGGCTCTCTCTTGCCCATAAGTTTCTAGGTACGTACGCACCAATAGACAGGGGTATGTACTTTCGGGTAAGCACTGATCGTGGTGTTGTCAATCGGCTTCACTAGTGCTAGTGCTGAGAGTTCACTGTCCTTCTTCCGTGCTAGTTAATGAACCGCTTTCTATCCGGAGCGGTCTTCTTTCGCTCACTTGTAACATGCGCTAGTGGCACTACCGACAAGCAAAGCTAAGGTGCCTCCTCATCGACCGGAGGTCCCTCCGAGTTTAGACGAGCTTTGTTCACTCAAAACGAACACGCTGCGCATAGAGCAGGAATCAGTAAAGGGAACAACCTAACTGCAAACACGTGGCGGCTTGTCGTGTCTGACTACCGGGCAGTTCGGGTCCTAGGCGGTTAGTGAGCGGAACGCGTCGCCGGGCGTATCCGTAAGGATTGAAATAATTCTCTAAACGCCCCGCGTCGAATCTATGTCCCTTAGGCTGTGCCCGTCATTTCCGAAGCGCCCACAGGTAAGAAAAGATGGGTTTTGCAAGGCAAGGTTGCCGATTGGCGTTCGCAGCTGTTTAACAGCACATGCCGCGTGCTATACGGCAAGGAGAGCCTCTACTCATGACCGTCATCACACGCCATATGCCGTGAACCCCCCCGAGGAGTAAAGCGATGTTCTGCTGTACTTACTTCACAATTGTTAGCCGTGGAATTCGCATTCATTCCAACCGTTTCAATGATTCGAGCAGGCGAGGCTCCTGGGTGTTTCGTAGCAGGGCCCAACCACGAACATCTCCTTAAGCATCCACCCACGTGTAGTATGCACACCATAGATGGCATATGATTGTTCGAATGCTACCGTGATGCGCCTGTCTGACCAAATACCCTGAAGTTGCGGGCGCTTGTCCAAAATATGTAGGCGGGACACAGGGCCAACGTATTCCCTACGTCCGTGTACCTAGCTCAGGGCAAGTTTCTTCAGATTCCATTGGGACCCTGTAATAAGCAGCTTTTAAATTACGCTCCCTTCAACGAGACGGAAGCGATTCCGAAGCACCGAACCCTCAGAAATGGACATAGCTGGTGTTGTGGTGAAGCCTGAAATCCGACTCGGTACTATTTGTCATGGGGCTCCGGATATTTGTTGATCTTCGCTGCATTTGCGTCAAACTACGACACAAGTAGGATGGGCGTACCGCGAATTCATGACATGCGCCCCGACTATCATGAGCCAGAATGTAGAATCCAGGCAGTACCATTGGGAATGATTCCGTTGATTTGCAGACGGCGCATTCACTCTAAAGACACATATTGCAAGATTAACCTTCACTTTAACTCATGTCTCATACGGGTTGTACCAGCTGCTAACAACTTGACGTGGATGGCCGGGAAAAGACAGTAGTGGGTAAGAGGCATCTATCAGCGATACCACTTTGAATATGAATTATCCTATTAGAACCGTTCGCGTCGGCTTCTTAAAGTTAAAGGTCAAGAAGCGCCGGCCATCGTTAGGGCACATAGTGGCTATGAGTTGCGAACGTCATAAAACTCGTATTTAGCGAGGTCTCGGGACAGGATAGGGTTGCTGCGTAATTGTACGCGGCAGACAGTACAAACGTGCGCGCGGCGACTCCTATCTCTCCCGCTTAAGCTTTATATCAGCCTGCGCCGGGTGTGCGCGCGAAGCGAGTCTGAGTCCCGGTCGCTAGTGATAAGAAGGCACGTGCTCCCGAATTGCCCCCCTCTAAGGTGTGGTCCTGACGAGACTTTGGATCACGCCTCTGCACAACCAGGGGTTAGCAAGAAAAGCCCAACCTCCTTGACGGCCGTTCGCCCAATTGTAATGTCCGATATTAGGCGAGCTCAAAGTTATCGGGTGCTAAAGCTTCCACTTATCTTTAGAGGGCGCACAGTTGAGGTACGGGCCCGAGAATCGGTTCTGCCACGTAGACTCTTATGTGGTGTCGTATGTGGCGTAGTTCAACCGCGTCACGACGAATCGTCATAAAGGGTAAACTATCCCTAAGGGTTTTGGAATCTTGCGCAATAGTCGCCTTTGAACGGAAGAAGCCTTACCCCTCTGCGTTCACAGGGTAGCACAAGCTGCGACGAGAGTTACTGGTTGTTTGAGGGGTGCCCTAGTAGGACCTCCGCCGTATTATGTACTATCATCCGAGTGGGCCACCGCGCCCGCCTTAAACACATGCTACCAGTCTGTGCGAGTTGCAGGTGGATCGGCAAGGGGGGGTCCGCTACGCATGTAACCATAGGGGAGGGGTAGCAAAGGTGCGAGGACCACATGCCGGCGTAAAAACGAACTCTCACATGTCAGGCTTTGCATTCTGCGCCCCATAATCATCTAGGCTTTGCCCCACCGTAGCGAAACAGTTAATGCTTTGTCGCTCGTGGCTTAACTTCCTACGCGTTCTAGTTGCTACCCGAAGCGGCGTGTGGAGTCTGCGTTTTTAAGACCGGTGTAGTTCGCATGCAGACGTGAGACCCGAGTTGTGCTTGTGCCTTGTGGTACAACTCCACATATAGTCGCAGTGCGCACGCAAGGCGCACTTCGTCGCTGGCCGGGTCGGGTCGTACGTGCGTTACGAAGCAAAGAGTTGTTTATTAGAACGCTGTGATCCGCACGTAAGACCCGTTACTAGCTGCTCCTCTGTTCTTGCAAGGAGTGGTCAGCACGTATACCAGAACAATATCCTGTTAGAACTGTTAGACATACGACACTTCTCCACCTGGGATACGTAGGAAGGTGCCCCCTCACAACTGATGTCTTCCGCATCGCAAGACAACGTTGCAAAATATTACCCAGCGCCGCGCGTAGTGTGCACGTGCTGGTCCCTCGCAGTACCGACGGTAGATTTAACTCCTAAGTCGTTAAAAAAATTGTGATTCTACGAGGAGAGGCCTACGGGTTCTTTCACCAATTCGATAACTTTCCGACCGTCATATTCCCAATGAATGGAATTGAACTGGACAACATATTACTGACATAGAATCATGCGAGTGATCAAGAGTTCAGGAGTAACAGGTGATAACCTCGGTCGTGGGCCCGCGATTAAACAGACCTTAATGCACTGGATCAACGTTATAACTTCTCTGTAATTGGACATATCTTGTATCCTACCCAGACACTGAGGCACGCGGCTGGCAAGCCCCCAGGACAAGTTCATGCTGCGATGGGCTTTATTCGGACTGCCGGGCCTGACCAAGGCCGATCTATGAGTAGGGCGCGGTAAGAGCGAGCCCCGTTGTCCCAGCCGTGCTGAGGGCCATCTGCCTGGTAAGATACACAAGAAATACGCCTAAATGTTCGAAGAAGGCCTTAGATGATGAAACGTTCTAAACATGCGCGCTAACAGGCCACACTGTATGACATTGCCAGTCTCAATGGGGGATACACTTGAATTAGCCAATGTCTTGCCTCGCCTGACACCACTCGACTTCGCTGCACGGAGCAGCGCTTTTCCTTCAGTAAGCCTATAAGGGGATCTCTCTAGTCACGAACTGCGGTTTAACCCGAGAAGACGTTCCTAGTGAGAGCGCGAGCTCCGAGTACGTTCGGCTAGACTCCGTGAATGGGAGACTTAGGAACTAAGCAGCGCGGGGTTTCGTTTATTGGTACTTGTGCTTGAGCGGACGGGAGCACTTCCTGAGGCACATGCCGGGCGGGGTCGCAGGTAGGCTTAGCAGAGACCAGTAGCTCGTCCGCCTTTCCTCCCGAGCGTGAAAGCGGTAGCCATACACGGGGCTAATAGGGAGCGCACCATGCCCACAGTAGGCCAGCCCGGGCCTCACTCCCCCCATTTTCAGGCTACCTGCAGAGCCATTCGGGTTCCGTGGCGTTTCAGAGAGACCTGACTATCGGTTTGTGTCAGCCGATAGTCTTGCGATGTAACACACGAAGGGATAAAAAAGCGGCCGCAGTGTAGTACCAGAGGTATTTAAACGTTAGACCGAAATTGAGTTTTCGAGCCTATCGAATAATTTCGCTAGGGCTAGGTGATCCATTGGTTGAATTTGCACGCTTGCAAATACAGGCAGTGTGTCATCCAGCTCGCCATAAATGTTCAGGCGACTGACAAGAATTCGAAACTCACACGCACTAGTATTAAGCTTGGGTCACCCTGAGGCACGGGCGATTGTTCCGGGATTGATATCGGACGCCGCTTTTTAAACGATGTACAATTATCATATTTAGCCCATAGGCTCGATCATTCAGCCTTATGCGAACCTCGAAGGCAGGCGGAGTTAGTCGCAGTCCTCAAGGTGCCTCGTAACAAATAATGGGCAGCGCCTGACAAGGGTTGATGTACACTCTCACAACACTCTTAATTCAAAGGAGCCCGCTTATGGATAAAACTAATCCCAGCATTATCTCTCTAGGCTTTTTTTGGGAAGCTTAATCTCACACCTTAATTCCTCGTTCGCGGCCCCGTTGACAAACCTCGACGCCCAGCCTTATAGGAACATTAGATACTCGAAATATGGCAGCGAGAAAGTCCGAAGTGGCTACAAAATGACAATTGTCTACATCGGGAGTATTGCCTCGGTCTTTGGTTGATTGGAACGGGGTTGCATAAAGTACGCGTACATATCGTTGCCGGATAGATAATCTCAGTATTATTCTATTTCATGTGTGTGTAACGGCTACTCCGAAGTCCTGTCAATCAAGACGGGGGCAAGCACAACAGTTCACTCACGGATAGCAGATTATTTACGGCTGAGTTCAATATCGGCAGGAGGAATTAATTTGAACGAAAATACACGCCCCCGGGCTACTGTTTAGCAAGACTATCATACGCAAATACTATGCCATTGCTCGGTGGAATTTCGTTTCCGGACCATGATAAACCGTGTTGTTATTCCAAAAGCGAAAATTTTGATTTAGATCGGACCCTAGCATCCAATGCAGGATCTAAAATAATAATGCGGATAAAATGATAAATTCCCTGCGATCGACGGACGCTAAGTATTGAAGAGCATATAAGAATTGAACGGGTGGCTCCTTCGGTTATGTGGCACTGTTTGCTTGCCTGGCAGAGTATATCAACAGTGATCAACGCGGGAAACTCGGCCGCGGTCCGATGCTGTCTGCTTGGTTACCTCCGGTTTACCATCTGGTTCTACGTCCACTTCGTGCATTTTTGTTGGGTAGGCGCACCTGATGAATTGAGCTGCCCCCGATTTCGCACGTCTGACATCCGAATTTTTTGTCTCAACTTGTCAATTCCGGATCGTCCTAGCTCAGAACCCACGGATCAGCTCGGATAATTTGTTTGGTTGTTTTTACACGTTTATCATACGAGCACAATGGATGGGGCTCATACCCCGGCCCTGCCGGCGTGTGACGAGTGGAGATATTCCTTCTCTAGCTGTTCCTTGTGTAGGAGCACGCTTGGTCCTAACCGTAGCCACTTCGCGATATTGAATGGTTATGTTGCAGCTACAACCAGAACTGGTTGAGGGAGCCCCGAGCCTCGATCGTCTTCACGTCCATACGCATTCGCCACCCTAGCTGGGCTTAGACGTTAAACTGCGACCGGGTAATTACCTAATTCAGTCAAGCGTCCCGTTCCACATTAATATTCCAGATTTGCTTAATGGCCCAGTTAAATCTATCATTACGTAATAGCTGTTACTCCCTAAAGCGCCAAACTTTTGACCCCTTGTTACTTACAAATAAACGGGTTGCGTCTTTCTTTCCACGGACCTCCATGCTCGAATATTGTCTCTTTCCGTATTGTACTGTACAACTCGGTGACAGTTCGTAACTACCTTCAATAGCAACCAACCCCTGTTACACCCGTCGGGCTACTAGTTTCTCTTTACAGCCAGCGTCTGCAGGTAGCTCAGCCCTCAGATTCAGACACAATATGAGGCTCAACTTTGCACTGAGTCCGTGGCCGGAGGGCTCTGGCTAACGGTTACGTTAGCATGAAGTACTGGCTTCATAGAGCCGGGCCTAGTCACACTGGTTGGACACTACCCGGATAGAACGCAAGTTATAAGATATAGGGCAGGTTCTGGGGTGTGCCTGGATATTTTTTGTCCCAGGTTCCTTGCGGCATTGCGTTCAAGGTCTCTCTTACCCAGTCGTCATATACAAGATAATACTATCGACAATCTTGACAACGTCTGTTGAGAGCTCGCGTCATAGGGACGGCAGCGCTAGGGAGGTATGCCCAACCGGGAATGTGGGGTTCTCCACACCGTATGTCCGATGGGCACAACTAGACCGTGTCATTATAAGAAGCTACAACCGAGATGCCGCACCTCTTTAATGTTGATCCTGTATTGTGAACTATCACTCAGCTAATTCGGGGCCATAGGATATAGGCTTCTAAGTCGACTTTTCCGATGAAAGATCACTATCCAGCGTGTCAAGGGTAAATGACATCAGGACGCTGACAATTTGGCTGAATCCTTGGCGACGCGGCAAGAATAAAGGCATAGCACGGGCGTTTGAGGGGACGCTGATTGGCTCGGGTCCAGGTCTGACCTCCACGGAGTCCGGATTCGAACTCGGTCAGTCACACGGGAGGCTTAGGAGCCTTCGAACGGACGATAATATCCCGTTACTCGCCACTGTGCCTGCCTATAATGGAAAAGACAACTTTTTGGAAGGAGCTCGCATTGTCCGCGGCCGAGCGATTTCATGTGGCTTTGTGAAAGAACTCGAGTTGGACATAATGTCTGTATATGTATCGCCGACGCGACATATCCTGTACGTGTTGTCGATGATATGAAATTGACCTACTTACATGATACCAAAAGGAGGCGGCCCCCGGAAGGTTGGCCCGAAACACGAGCTCCTCGCAAATGATGTCATGACGATGGCAGAAGCCGAGCTCACGTCTCATTCGGTCGCAAATCCTTGATTCGTGCCGTAAGGAACTTGGGAGGGTAATAGCAGGTGCCACGTTCTCCTATTGTCGGACGCAGTGCTTATGTAACTGATTCCCTGAAACGTAAGCTATTTCGTCCGGAGATAGAACATTATGTCCACAAGGCAAGATATGTTTCCTATGAGAAGAAAACGACGCTTAATGACTTGGTGTTCTTTCTCCAGGCAAGATACGCGAGCGCCTACGGAACAAATGACGTCGTCTACGACGTCCAGATCCCAGCTTTTCGTTCGCTGCGGCCCCCAACTTTGCCAGTAGTGCCGATTGTGCGTTGCGGCAGGGGTCCTTCATACTAGTGCTTCATGCATTTGCCAGGTACCATGGATCTGCACTACTATCAACCGGGGACCGCGCCATCGCTTATGGGGTAGATGATCGCGCCACATCGTTAAGCGCGGATTATCGGAAGCAATCGTCCCACGTATCCTAGGTATAAGATATAAGTTGCAACCGCCACTAATCCCTCACACTTTCCACGGTGGAATCAGATGTCAAGCACTACAAACTTGGTCCACAGATGGGCAAATATATGTGCTCATCTCATAAAAGGTGTGACCGCTCGTTCCGGAACCTCAACTTTTGCTCGTAGCGGGTATTCCTGACGCGATTCACCAATCGGGGCCAACGGCTGACTTAGACCCGGCAAATAACACAGTCCAGCGTAGCTTGCGCATTTACGGCTTTTTGAGCTGGCGTTCCCGCCAGATTTGCACAATAACATCGATGAACCTGTGCTGCGGCTAAATGATAACGGAATGGACAGTTCGCAGTGCTTCTGATTGAGTTCGTGACCAAAGTCATCCGTAGGCAGGGCACTCTATACCTCACGTATGTAGCCTGTGTATCCTTGCCCAAAGGCGCGCGCAGCTCGAGGAGGCGGGATTGACCGGGACACATGTATTCGCCTCCGAGCGAACGCAGTAAATATTCATACGCAACGAAAGAGCTTCTTACGGTATTAACAATTTCATCCGGGGGTTATCGAGGATCCGCGCCACGGGTCTGCGCGAGACTCACGTGGCGGCGGATGAACCCGGCAACAGTCGGTGCCCCTGCTCAGCAGAGCGTTATTGCGAAGTCCATGAAAACCTTATTCACTAACCCGGAACAGCCCCTTTAATACCAAGTGTGAGTAGAATATTCACGCATGGGCAGGGTGTGGCGAAGAGGCGGCCACACATCGACCGGAAATCTCTGTCCTGCGTTCCATACCCCGACGAATTTCATTTCCCCACGGACTAACTTTCAGGGGGAATAAGCGAGGTACCCCTGGCAGAAAAGGCGCAATGTCTGATGAAATTTCTCGTGATGCTCGTGTGGACGATGGCAAAGCTCATGGAATTAGCTAGCAGCAGTGAAGTAAAAGCCGCTTCGGCGGCGACGGAGTGTATCACATCGGGTCGGATGTGGTCGCGGAGTGACGAGATCGAGGATGTGAGAGATAAGGCCCGTAGATCGGCAGGTGTGTGCCCTACGGCTCACTCGTGGTCAGCCAACTGAACTCGTGACCCTCGTTATGGATCTTAAGCTCTAGTAGGACAGCCCAACTACCACGTCTTAGAAGCCAACGATAAGCCCATAGGGCAATGTTTTTAAAGGAGCCCCCGTTCGTTTCGGCCACAATTAAGAATTGAGTTGATCATGAGGACTATGTGATTTAAAAAGTACACGAAAGGCGCTCAACGGAGTGTACTAGGCATTAATCATCCGAGTACATGCTATAGCTTGTCCAACACTGTGCGATGCGGCGAGCGCGGGTCTGAAACGCACCCGATATTGGTTATGTGTTGGGGTGCCCATCGCGCTGTGTCCCCGGTGGGAAAGTGATGTGCCATCATACAAACGATCGTAAATCTGCTGATAAGGACAGACGGAAGGCTAAAATGGAAAGATTGAGAATTGGGCGACTTTCTTTATTCTCAGAAGCAGGAATAGTCATCCGTAGTGCCGTCAGTTAGTAACAAATAGTTGCACGCTGCGGGGAAATCCCCCCACTCCCGGAGTACCCAGCAAGTTAGGAGGGTGAATCCCGGTTGGGCTCAGCGGACACATGGTGCCGACCAGTATTTCCGCATTTTACGGGACCCATACAACGCGTAACGCTTGACACTGGAAACAATAATAGATGTGTCATGAACTTCTAAAGGTCAGTTCTGTCGTCGATCAGTGCTCTCCGCGATACCCGAATGCGATTCTAAGAGTGCAGCTTTCCCTAATTTGCTACGCGACGTATAAATTGGCCTAGATTGATGGGTGGCGTAATGAAAAGTTATGCTGTTGGTTCGTATCCTGTGTATTTCGGTTCTTCAATTCGCACAGTGATTAACGGCCCATGACTGATGGACGTGGGCGTGTAGTATGGGTATACCCCCCTCAATCACCCCGAGTGCACCTTCGTGCGAGAAGCACATCGCCTACATGATTGGGTACCCCCTAGCTAATGACACCTCCGGCCGGTGCGGCGGAGTCGTAGAATGGGCCAATGATTCATCCCCTTGTTTCGTCAGTTCAGGTCCTGTGATGCACCGTACCTGCCTTATCATTCTCGAAGCCTGTTTAAGTTTCGTTTGCGAATTCTGCGGCCTGCTCTGATCCGGGGAGACCTTCGAACATGTGGTACCGAGACTGAGGTGAGTAGTTCAACCATTTAACTGGAACAGCTAAATGTCGCTTTCGCCCCTTACTTCTTGTATCTTTCGTGGCGTTACCATGAGGAGGGCATTTCTGACTGTCGCTTGGATGGAGGAGTAGAATAACCAGTACCCTATTCTGGCCCTGTCAGCGGCACCGGAAACCGGGCCGCACGTGTGTTCGCAGTCATTTGTTGACGAAGCATGCGTCCAGTGAAACGTATCAGGCATAACTTGCAGGGTAGGAAAATAGGCACTCGTAGCCTAGGTGCAAGGCGTTTTATGGCGCTAGAACTTAGAAACGAAAGATCCGGAGCTGTCCGATAACTAGTTTAAAGAATCACCATCGGGGGATTGCCAAACGATACTACCATTCCTTACACCAGTGAGGGGGCGCTTAGTGGGCATGGAGTTGACGCGGGATGCGCGGGCCAACAGATTCCAAAAAGTGACGCTATTTAAAGAGGTGGGCTATGGAATCGGCATGCTTACAGCTGCTCTTCCTCCTGTAGTAAGTATATGCGACCGATGGAGGTCAAAAGGTCTTGATTCGTCGGTGGCCGATGTTATGCGGTGAGATACCTCCCAACGGCGTTGATAAAGGAGGAGGCTTACCATTACGCCCATGTTCGAGCCCCCAGCCAGACATCGGTACCAAGAAGGGTAGTTGGATACACCCCGTTGCCACCAACGAGTGTCTTGTGATTGGCCGATTTCACCAAGGGCAGATCGACCTGGCGTGGAATTCCCTTATGCAACAGAGTCGACAGTTTGGGGTGTAACAATTGTGCGTAGGCCCAGCCGTCGAGTGGTCCAGGGCTGGTACTATACAGCTAGCCGTACAGAATACTCGAACATTGATCACCATGTGACACATCCGAATAAAGGCTAGCTACTTCCGCACAAGCAGATATATTGCCCCGAGTGGATTCCCTGGGGTCTCTGAGGTATGGGGATAACATACTTTTTAGGACTACAGATAAAAGTCTTACATGGAAACCAGCTACGCGTGGTAAACGGATAACGCCACCGGATGTTAATTGGCCTCGCGAGAAGTTTCATATGCACTTAGGGGTCTTAAGCCGTAGCGCTCGGTTTATGCGGCATTGCGAAGTCTGACGAGGCCATTCGACAAGTCCAACAACTTATCACACTTGGTTTGTGCTGGGCTGTGAAGTCTGCAATTGCAGGTAACTTAGCACTCCGTGATCTACACCCAACCGGCCGTACCTCTTGGGTAAAGAGACTGACCCGGGTGTGATATCTGTGGTAGCCAGGTGTTCATTCAAATAAAAATTGTCCTAGCATTCCGACTCTAATTTTCAAACCGTTGCAAAATTCATCGTTCTAAAAGCAATAGCTTGAGAGGTCCTTTTTTACGGGTCACTGCATCAATATTCTTTCCTCTACCACTCAGTTGATCTTAGTCACGGGTATAAAATATCCCTACTGTACTGTTTGCCGGGCGCGACGGTATATTACCCGTGGGGCGGCGCCATCCGATAGACTCGTATATATCAATCACTTCCGCGGAAATTTTCAGCGTGAGCCAATCGATTGACACAGAGTCCGGCACCGGGGTGACGCATTGAGGTCCATGACACTCGAAACTTGGGCTACGACAGGCGCGGGACGGCCGGCTCGTTACTGAACTGTCAATGGGGATCGCGTGCTTACGGTGCGCGAAGGATTTATTTGAACGAAGGCATCTTCTTAATTGTCTTCATTAAAATGGCCTGGTATATAGTTCGCTAGGCGTTTCTACAGTACGGGTAACTTTCTCTCAAGCAGGAACCGCAAACGTCGATGCTGCAGTGGCATTACGGGGTGATCTTAACATCAAGGAATATCTCCGGTGATTCGACACGTCTCCCCACTTAGCGCGTGACCTCTGACAGGTACCGACTGTAAAAGATCTACGTGTTATATTCAACATTATCCAGCAAGTCGTGGAGTGCGTACATGTTATTGTTTGTGTACTAGAACACTACTATGACGGGTGGAGCCATCATGGTTGACACGGAAGGATAAGGATTGCGCACCCATCAGGAACATGTACTAGACACTGCGCGTTACCACCATAAGCCAGTGCCAAGGATATTGGAACGCTAGGCTTACAGTAAGGCCACAAAGATGAGACTCCTAGATCGTCTGCCGTAATATAACAACTGTACTGCTACAACGACCGATATGCGCATGGCATGGATGCGTAGTTTTCAGGGCATTCGGTATACCGGAGCTGTGCCGAAATCACCGTTTCGGCCACGACGCTCACACGATGGTCTGTGAGACAGGGGGGCTCGCAATCTTCCCCATGAACATGGCGTGATTCAAGAGGAAGCGGTGGCGTGTTCGTAGGCGGGGCGCTTTTCATTTCACGAGAGTAAGACAATAGCAAAGTGACGGCCACGATAAGGGAACTAGAGAAACGAAATTATATTACACGTGCAGTCCGGATGGCCTTGCTGATGTAGCTACATGTCCCACTATTCGCGTTGCTACAGGGGGTCTAGGCGTCTGTCGGAGATTCTATTCAGAACATATGTACAACAATCGGCTAGGACCCACTGGCTAAACGCCTGTGGCAGAGTCTCGCTTTCTGTCAAGTCTACACTAGTAATAATGGTCGCGACTGTGTGCTTAAGCGATCCCGGGCGTATCCGATATGAGAGGTAAAGGTATATTGCTCGTCCCGCCCCCATCTAGGTGCGCGTTTTTCTAGATGATTCAGACCCTCTAAGCACCGACGATACTAGTACAAGAACTCTCCATGGTACCCTCATGCAGCTGTGACGTACCGTGTAAGTATCACTGTATAACTACGATTGGGTAATGCTCGTGTACCTGGTCTATAGTTTACGTATGGCACGTGCCAACCGCGCACCTTTTAGGATTCGAAAAGGCTGCGATCGCGGATGTGCTGGCTCGCTTCACAAAGAATAGGGCGCCGTATTAGCTCGCGGCCGGGTTGCGTTCCCGCTAAGTTACTCTATGCACGCTGGTATAAACTCTAGAGATATAAAATCATGAGCCCAGGGCGGGTTGTAAATATCAGCAACGTAACAATTGTGTGCGTTCCTTGGTATCTGCGCAATCGCGATTCTGGGTTACCGCGAGAGCCCCAGGTTCCGGTTTTACAAGTACAGGGCACAAGAGAGATACAGATGAGTGCACGCAAGATGCATTATCGCCATAACTGAAATGGAAGTTCCTTCCGCTAAAGTTGTACCGCACCGAGAGAAACCATTACTCCAAGGACGCTACAACGGGCTCATCTTCCCGTCAGCGGGTATGCAGTATACTTTACGCGGCCGTCCAACATCCCAGTCTATACCTAACCTTAGACATCGTCTTACAACAGCCGGTATCCCTGTGACCGCCCTACGTACGTTGTGGGTGGAAATCAAAAGACTAAATCAATGGATTTCGATGTCGGAGTGACTTTACTCCATGTGAATAAGACCGGACGAACGCCAACTCGAATTGTACCCGGCTCTCCTTTATCGACAGATGCGTCAATACACAGCGAGATCTATGCCTCGAGCAAATCCGGACACTTGACGTCTGCGATCGTAGAAGGACGGTTTTGTTAATCGTACAAACTACCTCCAATATAGCCCCTCGTACTGTTGACAGCGATACGGTGCTATGGCACTAATCTTCACTGGCGTTTATGGGTATGACAGCTTGGATCATTTACCCCTGACCACTCTTACATACGGAAGACAAATTCCAACCAAGCGCTGGATCTTCGCCAGTGACACCAGAATAGTAACCGGGACCACACATTCCTCAGCTGAAGGAAAAGGTAGCAAGTCACTGGAAGGCCTGGGCACAGGAACGATTGCCAAAATTCTTAAACGAGGCACGAGTAGTGATCCTAAGGCACGGAAACAGCGCGTGGCCGATCTGTCGTGCACCTTGTGGTACTTTTCTGGACGAAGAGCAACGTGTATTAACTCTTAACGCTCTTCTGACATGGCTCACAACGCAACAACGTACCGTTTAAGACTCACGGACACCTAACGCTTCCAACCCCCAAGTATTCACGATGCTCCCTCCGTCGTATACCACTCGTTAACTTGATAGGCTTGCTGAAAACAGTGCTCAGGCCCGGTCGGTCGCCTGTGGTAGCTACCTTACTTTACAGCGAATCTAGCGATAAGTTACGTTCAAACAAGACTGACTTTAACGCCGACGGAGAGTTAACCAATGGACCTTCCAGCGGCGCTGACTGTTAGGTGTGCAACTCCCCATGCCAATTAAAACCAATGGGCCTTACAAAATATGATCTGAATGTCCACATTAGTCTGGGAAGAGTCATATTGTGTCCATAGACCAACTTATCAATAGCCCCAGATACTCCCTTGCGGTATGGAGCTAGCATAGTTGCTTTAGTTATTTGAGAACGTGAACTTCCTATTTGTTGTTTACAATTCTAATCGTCTCCTATGCGAACACATAGAGTCCTGACCTAATTCGTTACGTGGCTTGGAAGGTTGCACAGGTCTATAAAGCCGTAGACAGTGGTCCAGATCGTCTTTGCGTTAATTCGGGACAAATCCCTTCCAGTTAACGTTACCACACGGGAGCTCCTACACGAAAATGCTCTTGGGTGTCCTATAACCTGTACATCTACCCAGGCTCGTCGCACCCCCAGGGAAAGGCCACATCTGCGAGGGCTCTGGCGGACCGTGAGTCTTTATTCTTACTCCAACTCCCCCGAAGTAGGCACTGAAGGCCGTTCGTGTGACAGTTCGACCCAGCAGCTCCGCCGTAAAATGCTACAGAATGAGTGACCCCCCCAGTACGGACACAATAGATTGTCCCTCGTCCACCGATATGCGACGCAATTATGCTCGAGCACAGTTTGCATACGATGCCTACAGATGGGTACCACTTGGGCCGGGGCGACTTTCGCCGGGATTGCCGAATATACGTAATGCCGTCATCGGGCCATTTAAAACGGGGAGACTGGGTGGGGAACAGTGAACCCTGAGGCTAGGCGCAAACATTGAGGGGATCGGACCGTTCAAGCCACGAATCCCACGGCGAAGATATCTAGGAACATGTAATCTGACGGATCTCTTACGAAAATCAGAGAACTGGTGCATCAGTGTCATGCCTTTTTAGACATCATATACATGTCTTAGCACATGGCAATTGGGTGCACAACATCCTTGAGTCGAATTCCCTACCGGTTAAGGGGACGTACAGAACACAACATAGGAAGTCTAGTTCGATGACGATCGAAAGCTCGTGCAACATTTACATTTCACGACGGACTCATTAACGTTGCCCCGGCGTGATATACGTCTGCCACTCGGCCCGTCGTACTAAGGTAATCCACTTGAAAGAGCAAGGTCTCTTGCAGGTGACAACACGTGCCTTTTCCGGTACTCAGGTGAATATATCTCGTCCAATGGGCCTCGCCGCAACTATCACCCTCGTTATCGACGCTAGGACGGTTGGGGATTTCTGCATTGGCTCGTAACTACCATATAAACTTTGCAAACCGGATTCCTTGCGTAGGGACCTTCATTGATATGGAAAGCTGCTCATCGTAGGGTATTTGCGCCGCGCAGTTTAAATGTCTTAATGCTGCGCCTCTAACGCTGTCATAAAACGTTTTTGTGAATAATAGAGACTAACTTCCGCTATTTCAAGTGAGTCTTGCTGGTCAGAAACAG . PASS . GT 0/1 0/1 +20 600000 . CCCCGTTTATGAACTCAGCGCCGAACAGAAAAAATAGCCCCACTTTAAGTCCGCTTTAGCGACTCTAGGGTCCGAACGCGCTGTTTCGTACATGGCACGTCGGTAGGCAAGAACTCCCGTCCTCAGATGAAGATGCGTAATATCCTTACGTATTTTGGAACTCAGGCTGCCGAGCATCTTATTGGGAGACTCTTACCACTTTGCCCGTAAGCAGGGAAACGACATTTGATAAAGGATGGCAGGGAAGCTTTTATGCCCCTTTTCCTACTACAACGTCGAATGTTGACTTCCTGGTTAGCGTTGTGGCCTTGTACTGACCCTACTAGGGTTTCAGCTGCCTAGAGGACATTCGACCGACCCACGACCGCAGCTCGCGGTTCATACACGAGAAGCTACAATCCGCTTAAGTATTTGTTCTTTTCGTTCTAGGGCCCGCGGCACCAAGGAGGCTTCAGAAAGAGAATAATTACTCGATCGTCCCGTAAGTAGTGTATCGCTAACAGGGCCTGCGTCGTCCATACTAAGGCAAGGTGCTCCAGCAGGGCATAGGAATTGACCGGCGGGTAACATTGGAGACAACATGTGATTTGTTGCTTAATCTCGGTTAACCCGCCCCGCTGTAAAGGCGAGACGGCAATCATGAATTCTAGCACGCACCCCGCCCGTCTCTGTCTTCAAAATGTATTTTTGGCAACGAAGGATCAGCCTGTCCCGAATCGACACTGTGTTCCTATGGCGTAAAGAATTCTGTTCCTGAATCGCGGGCGCACCGTAATTCTTACTTTCACATCGAATTGTTAGATGCTGACGAGCAGAGCGCAGTGCGGCCGGGCGGAGATTGCAGGGCTGGCAGAGCCATTGGCCGTTGATGGTGTTTAGACGCTAAGCTAACCCTATGCCTCATGGATACTTGCTACACAACAGTGTCTGCGTAGGCTGAAATGGGGACGGCATGAGACCTCAGTGTCAACACAATTTGATGCACTGGGTTTTCTGCAACTACTTTACTACGGCTTTGTCCTTAACGCGTTAAGGGACTCCATCTCATCCGTATCATAAACTCCGTAGTGTATTGGGGCCAAATCTAGAATACGTACCGTCGACAATGCTCACGAGGGTTACTCAAAACTCGGCGGGGTGCCTCAATCCGCGTGCCGTGAAATGCCCGTATTCACGACGACTAAGCACTTAAGTCTCGGGAGCTCTGTTGCGTCTCGTCTAAGGGCAGTCTTGCTTCCTGTGTCTGCAAGTTCCTCTCTAGTGTTTAGGGTGCCTAATATACTCCACGTGTGTCTATGGACTCCATATGGTAAGTAATGGTGTTTGATAAACCCCTGGCCCTTTAGGTTCTACCTAGCCTAACTTCTTCCTTTGACTTTTACCCCCATTGATCCATGTTCGTCGAAGTGGCCGATTGAGGCTGCCGCATGGCCAAACCGCTAACCCGATCGAGAAGGTTGCAAGGGCGCATCCGCAAATAAACCATGGTTGCTAATTGGGGTGCAGGCGTAGAATTTGTCGGTTCAAAAGGCCCTCGACCTGCACAATGACTTGCGCTCGTAACTTATGATAGGGCCGGCATGGGATTATTCGAGGGACTCCTCACACTCAGAAGTTTACTCCCGGAGCACGACTTTACGAGGTGTGTTGCTTTATGATGGCATATAAAAAAGATGCACCAATCACCAAAACCCAACTATCCTTGACACGATCAGTGCGCGACCTACGACTACTCTAGTGGTACGACTATCGCGATGGAGGGGATATTCGTATATTTGAAGTTCATGTATTGATTCGGTTATGGCGTCTCCCTTAGTGTTTATGGACTTCATGCGTGCCCCTTATCCGCCCGCAGGCACCAATCACATTGTGGAGTTAGTTGGAGCGAAATTGGGTGGCTGTACGGTCAAACTAGAAGCATACCTTCACAAGGGCGTGGCGCTATGGGAAGTGGACCTGAGGGACACGATGGGTGAGATTCGGACACTCTGTCTACAAAATTAGGAGGTACCTACTGCTAGCGAGCTTCAAAATTCGGGAAGAGATCCTCGTACCACGTATTAATGAAGAGCCAGTGGAGCGAAGAAATTATCGCAAGACCGACCCTGTGCCGGCAGATGGACGTGTTAAACATGGTACATTGAGCAGTCCGACTCGTTGTATAGTTACCACGTGTGAGAAGACTTAGCTCGCAGCTAGTGGACAAGAACTCGGCCGAAGTTTCGTTCCTGTATTGCGCGTGTCCAGGATGTGAACAGTCCAACTTCATTATTTTATTCTGACTTGACACTGGACGTAAGTCAGCTGCTCAGAAACCGGAGTTCCCTGCCTTGGCCTGGGGGCCCCATTTGCGGATGAGCCCACAGGTCTCGTAGACTTAGGTGACGCCGGGATCTGCTGGCCTTATGTCCCTAGAAGCTTGGATGACCGGCCCACGGCAATGCGTAGTCAGGGAGGTATCCATGACGTGCGTGAGTCGGGCGAAGAGGGCCCCACATGCACCTAGAATAGCTATGTGTGTTTCTCGGGCGGAGCCCGACGTCGTCCCGCTCATATCCAAGTGCTTTTTCCGGGGGTTAAGCGGTGGCTTGGGCACAAACGGTCGCCTCCGCCCGCTTGGTCTCTCAGGTATTTCCGGGGGCACTCATAAACTACGAACGCGATCTCCGATAGCCTTCAGTTGTGGGGATGCGGCTAAATCCAAGCAATTGCGACGCTTTGGGTGTGGTGGGGGTTACTGATCCGGACTGCAAATTACTAACTCCGTCACCTATCAACACGTCTCCCTAATCTGTTGGAACCTCGCTCTATGACATCAGAATGCGAGCGCGGACATGGGACATGTCGGGACAATCTATTCTGCCTCTCCGGTACTGGGTACGATAAGCGCGACACAAGATTGTGCTCTTACTTCGCCGTGTTACCGGGTAAATCGCCGGGATGCTACTCTTATATGTGCCTTCTCACCTGAAGCCTTGCGACCTCGAATGATTTGGGTGTGAGTAAGCACCCGGGATCGAAGCTGGTAAGCACGTCACCATGTTAGAGATACTTGACCGACGATGCCCTTCTACGGCTCGGTTCACGGTGCCCAGCGGGATCCTCTTATCCCAGCCGGTGCCTAGCCGATAAAAGCTCACAAGCTTAAGGCTCTGTCAGGGGAGATGTGGGAGAGGCTCGATGAGAAGTCCTAACGACACCAGAACCCCAATTAGCACACATGGCTCTTCCGGGGACTTGGCTCTCGTAACTGCCTGCAATGTACTACGTCGCATGCTCATGTACCAGACATTATGTCCGTCCTTAACAGTCGTATTGGAGCAAGTTGTGAGTACAAACAGTACACAAGCTGTAGGTCACTCCCCCCACGTCTACCCTATATACTATAAGTCCTTGTAGCCAGGATGAGTAGGCCCCGTGTACCTTATTTGAATGCGCACCCGTGACTTCTGGTGGAGAACTTGGTCACGTCGGGTGGACCGTGTACGATACCCCACAGTGCCCCAGGAGGTATGGAACGATGCTGCCCTGAAAGGTGGAAGGCCGGAGTTTTTGTAGTTACAAACAGTACTCAGCGCTATCAGCAAGTGGACACGGAGAAGTAATTGAATGACCGCCTAGCAGTGCTCCGCCTCCGGGCGGCAGCCCGCGTGCCTCAGTCAGAGATCTCGAGCACGCACCCTTGCTGCTTCCGACTAATGGGAAGAAGTGGAGATGGCGACCCCCACGCGTTATAGTCCCAAGGTTGCTTCCAGGAGCTATACCCGAACCTTTAGGTCTAGACTTGTCGAGTTTGCGACCGTACTCGCTTTGTATGTCGACTTTTTTGAAAAGACAACCGTGGCCCGGTCACTGTGTCTCCAGTTTGGCGAGCCGTAGTCAGTGATCGCGCTGCTCGGGATCAATTATCTCCAACGGTCAGCAGATCTACGGAGTCGGTGGCCGGTATAATGCTGGAGGCCGGTGTATGCAGGAACCTAATAGTCCCCGAGTGTCGATCTGTACGGGAGTCACTAAGATAAGGCAGAACTGACTATCTCTCCACCGCTACGTAGTCCAGTGCCAAGGTGTGGTCATGGCCCACATAAATCAAGGATTTGTATGCTAGAATTACGCGATCGAGTGACACTCAGAGTGCACTGGCTAAGGACTCTAGCTTTGTAAAGACAGCATTACATCAACACTCGTTGCATTCCTAGACTGCGGTTCCTTCGGGATCTCCCCTTGGTACTTCCTATATTTCCTGAGATGTGGGCGCAAACAAATGCCAGATCCCGCCTGTAGGCATTCGGGACGGGTACTACGCGATGACCATATCGAGATTGAATCTTACGTATCTCCCTACAAGTGTGGCTTAAGGGGTTAGCACCGACAACTCATATAAAAACCAAGTAAAGAGAGTAAACACAGTGCGGAGTAGCCGTACTTGCGAAGCGCCATTTGGGCGCGACCTTCCGAATTTGCATCCGACGTCGGTCGTATAGCAAAGAGCGATTCTGAGCCTCCAGTCGCGGCCACGTCGCCGCTTGGCCAATGTATACCAGTTGTGAATAGGTCGCGGAACGCTAATGGAAGTAACCCCTCCTATTACCAACACGCCTCAATCGTACCACCGGTACCCACGGCATATAGAGACTATACGGCGTCGCGGCGGGCCTCCTCATGCTCGTATGGACTACACACCATGTCCTAATAACCTTGGTAACATTACGCCTTTGAGGGGTTCTTTATCTCCGATTTCGCGGTAGATAAGGCCACATGACATTTTCCGTTCGAGCGGACACGTGTCGCCTCAGTAGCCTATTGCCGTCGCCCAACCTACGCCACTGGCTCATGCCATGCCATCTCATACAATTAACTCCCGACGTTCGTACCAGGTGTACCAGGGGGTCCATACTAAGAGAGTGTGACCTCCAGATTCTAAAATACTATGTGAGGAAGTCATGATTTCCTCTAGTCATTGTGGCACCGCTCGTACCGTGAATCATATCAGATAAGAACGATCAGTTTGCGACTGTTATTCCGAGGGTACAGTCTTTAAGACACCATTCGGAAACGAAAAGGGACTAATGGATGCCGCGAAAAACCTAAAAAGGAAACAAGCTATCGATCTGTGGCGCCAAGGAGGGCGGGGCCCCGCATGACTCGTCAACTCCCATAGGCACCGCTCCGGGCCGGTAGCGACCGGAAGGCAATTGCTACCCTATCATATAAATGATCCTGGTCATTAGTTGTGCCCCGTATACTTGAGTCAAGTATTCCGTCGCAGAGACTACTGCTCATCCGAGACAACTTCTTCTCTAAGCGACCCGGGCGGACAAATTCACACGCAGATGGGAATTACACTAGGGGTATACTCACCCGGGCCTAAGGAAGGCACATGAGTGGGGCGGGCTGATTAGCAATTGTATCAAACTAGGGTCAGGCACACATAATGAAGGAGCAAATACATTGCACGGATATAGCCTAGTCGAGTTCGACGCGGAAGAGGTAGGCGAAATAAACTGTGAAAATGGGCAACACCTCACGAATGGTCATGAGTCAATGTAAAATCTTCGCGGCTTACTCGGCCTATTGCTATCGTGACTCCCAGGCCCTCAGTCCACCTCTCGTCAGATACTAGTTCGGGAGGCTCGAGATAATTGACCCTCCCTAATTCAAACTCAAACGAACTCACGTACGGGTAGGGCACCTAATTCGAGATGAAACATGCCTAAACGCCTCGAGAATATGTCTGTTTTGTACATAGTCTGTCGCTTATTCCACCACTTCAATCTGAAAATAGCGGACTAGTCCCGAGGGCCCCGATTTGACAGGTGGTTGAGAAGATCAAGTTGCACGCTAGCACCAGACCCTAACTCGCAACTGCTCTGCCTGATAAAAAACACATGAATCTGCGAACCATAACCTTCTTTGCCATTCTTTGTCTGCGGTTAGCGATGGGGGGTGTAAAACCACCTGCAGCGCGTCCCGATGATAAGCTATATGGGTTCACGTGCAATCCCAGAATCCTTTGGGGGGTGGATCAAATTGAAGCGAACGCAGCGTTGTATCGACGGTGAGCCCGCACATTTGAACTCGTTCCTCGGGTTCTTCGATGAATGTGGACTACGCTAGTTGACAATGCCTGCAAGTCTCCTCTCTCCCCCACGTGTAATATTGTACATAGTCAAGAAAGCTACATGCACGCCGACGTATCTTCTGTGCTTATGGATCGTTATAAAATTTTGTACTTACAGTGAAAATATGAAGGATGAAGCCTTAGAACTCGCTGCGTGAGAGAGAAACCCACCTATAACAAGACGCACGTGGCGCACATCCGTCCCCAGTGTTCAGCGACAGTTTGTCTAGCCAGTGAATCGGATCAGGCGGTCCTAGAGGTCTAGGCGACTTATGATCTTAGTCAGTAACCCCAGTAATTACCGTGATTACCATTTACAACGGTTAATTGGGTTGGTCTATGGTAACGCACAAATTACTCGTCATACCTGCTTAACATGCCTTCGGGAGTTAACGCTGTCGGGCGGGGTCAGCTTACATTACAGTAATCCGGCAAAAGACAAACCAATGCATCTCAAGAACCAACATAATAAAAAGCCTTATCAAATCTGGATCACAACTAAACGTATCACAGTAATATGTATCGCGAGTCTAGGAACTTGAGCACCCAATCATCATCCGTGGCGTCTCCGCGGGCTCTGAACGAGAAAACTGGGCACTCCCGGCTACTTTGAAATCAGGAAAAGGTCATCTGTTAAATGTCTGTTCACGATAATAGGCTATTCCACTTCAATACATGAATGACTTAGGATAGATATTCCCCTGGGCACGATGTTCTTATGGAGTGCGGGATTTAGTGGATATTCACGCTTGTATTCAGTCCCCTGTCCCATCACCTTTTTATTTGTCCTCCGCCCGGATTCGTTTCGTGCACGGCCAACGAGGAGCTGTTCATCAAATCTACCGACATTAATAAGTCTGGCCTATATGTCGTCCAACTAGGGACCCCTTTCAGAGTAGGTGGAGCTATCGTAGTCATCAAGTCACAAAATGAGTTCCTTTAAGGTGGCGATGTGTTGGGTGCAGACAGTATAGATAACACTCGGCATGGCTTTAGTCCCTCTATCTCGGATGCGCGCATCACAGATACCGCACAGGGTCCCACCTTACATGTTCGGTTGGGACTGAGTGGAAAAGTTGGACCCTAATGGTTGCTTCCGCGAGAACAGAGACTTGAAGCAGTCAGTCAGGGATTCAGTCCGTCAGATAGGGGTGGAAGTATGGCCGGCGGCCATTTGAAGTCGGCTAGCAGCAAATAAATTGCGTAAATATGTTGGTGTTTGGGACAAGGAGGCACGGATCCAGACGTTACTGAGTCCCCGAAAGCGTTACTCACGGATACACGCCATACGCTCTACTAAGAAGAACCATGCACGGACCATTCGATACAGTCTTTCAAACGCCAATGAACCAGGAGCCGGGGGGATGAAGGTGGGTTGGAGGCATCGGAGTGGTTGGGAACTGGTAAACGAGAAGGCCTAAGAGTACTCCCAACGCGGTGGGTAGTATGTAGGTTGGTTTAAGTCGCGTTATCTGGAGCCCGATACAGAAGACCATCAGCTAAGAGTGGTCGTAAGACAACAGATAATCCAGGCATACTAACACCGTTTTATTAACACCTAACCCGTGCGCGGGCAATGATCTGTGATTTCGGCGGAACCCTTTAGCAATCACTCGAATGCTCCCCTCAAATTTGAAAGGCATGACCTCCGTTGTACGCCCTGGATTTCTTAGGGATCGATTAAATTGGAGGCGAATCGTGTGTCTGATCTATTGGCCAATTTGATAAATCGGGACAGAAAACCCTGGGCAGCTGTATCCCGGCCAACTTGACTTTCACCTTTATGCTATCAGAAAAATCGGTGAAACTGAAAGTCTCTGAAGTTCTCTGCAGTCATGCGGGTACACGAATGTGAATATGAGCTGTCGCGAGTTAATAGGACAGGCAGAAGCGCAGGTTGCGTCCTAACAGGAATACTCTTAAAGTAGGTGCGAATCGAGCAACGTCATCGCGTCAAGCGCGACCGCTTCAGTTGGTTGGAGGCTGTCGGCAGGTTCATCTTGCCAAATCGAACTAGCAGTGGCTTCGTTACGGGCCAATACCACCTCGAGGAACCCGGGTAATGAGGTACAGCTTACACAGGCAACCTGACAGAATGGATGTTTGACCTTCTATGCTGTACGTGTTAGCCCAACACAATTAGCAAGATTGCACCGGCGCTAACAATGTTAATGAGGTGTACTAAAGAGGTCGTACAGACAGGTCATGGGGGTAGGCGTATTTTCGCGCAGAACACGGGTCTATCCCATGAACGTACAGGCAAAATATTCGTTCTAGGAGCTGTGGGTCGGTTCCGTGGAGAAAAGTCGCAAGGCTATGTAAGCATTCATGCCTAATCCTCGCAAAAAGTGTGTGGGATTAGAAGCGTGTCTGAGCAGATGTGGTGCGGGATCGAAATAAGTAGGTAACTACCACAGCACACTATTCCAAGCAATAGTTCGAAAAAGGAAGACAAACCGATTCGGTTAAACTTGTGGCGGTCCTTTATTGCGCTAGCGTGCACATACTTATAACCGTTCCTTGCTAGATGCCAATACACGATATTGGCACATCAGGTGCTTTCACCCGAGACAAACGGCCTCTGCTAGCAATCCCGGGTCGGTAAAAATAGAAGACGAGAGGACGGCGATCATATCGTGCGAATAGTATCAGGCTTCATATGGGCAGTTCGCCTCGAGGACTACCCTCGTCGAAAAGCTTTACCGGAAGATGCCAAACCCGGGCAGCGGCACCAGGCTGTTACCCGTACTCCTAATAGCTCGGCTAAAACACGGAGAATGAAATACCTGTACCAAACGCACGTTGAGCTTCATCCACCTCTGGCGTGTGTACTATCCTATAGCGGATTTCGCCGGAGTTGCCTTTTCTCCTTGAGTGTTGATGCTGCCTTCTAACAAGCGCCTTTGCACCCAACATCGACATTTAAACTTTATTATGGGGTTGGTCCTGCTCCGTGCAACTGTCCTCTCTGTCACCACTATATTAAACATAGTCTGACCTAATGCAAGTTAGTAAGGAACAAGAGCAGCCTCATAAAGACTTGGCGACGCGTTGAGACACATATTGGGTACTTTAGGGATAATAAGTGTGAGGTACGAGGTGCGCGGACATTATCTTGATGCCCTTCTTGGAAATGTCGTATTTCAGGCCCCTGGTGCGGAAGAACTTTGGCCGGGTTTACATAGTTTAGATAGTCCTAGGTACATCAAGACGCCAGTATGAGTCCGCGAGCCGGTATGAGTCATATACAAGCCAAAGGGCCGCCTCCAACTTCTGTATCCGTAATTTTCTCCATAGGGCTCTGACCAGTATTGACCCCAAAATGTGGGCTGCAGATCCAAAGAGTTAACGGTACTACCCGAGGGATCAGTCATTCACTACGGTGCGCCTTGGATGGGATCCTACCGTTGAATTCGTAGCCTCCTGCGCTCCGCTAACCCTGACAATATGTGCACTTCGCCTGGACGTATTGACACCTGAAACGAGCACTGAGCGTAAAGCTAGTTGTTATACGTCACTGCACCATGTGGCGGGTTATAGCATCCTCCCATTTAGGTAATGCGAATCTTCACAGACATGACGGGGCATGTGGACTTACCGGTTACTTCGGGAAAACTGGCAGACAAAGGTTGGTTATAACCTACCAGCAAGTCATAATCTGTTTCAGGAATTACGCAGTTCTGCCGCTCATCCTAAAAATCCACCGACCCTCGCACGTGCCGAGTTAATCTACGGAACGCATAAGAGAACGGAAGCCCAACTGGAAGTTGGACAATGCCATGAGCGCCCTCGGACCACCCTCAGAGAGGTAATTTAGGGGAGCTAGGTAATGATCACGCTTTTCAGTGGTCCTGTATCGTGCATAGGGAAACCACTCTGGATAGTGCTTCTAGCGAATCGTCTAAGTACCCCATCCTTATAGCCCTGCCAAAGTGCTGGTAGTAGCTATCCGGATCACCACGTTCGGGGGACGGGGCGTGGCTCGTCCGTATGCTGGCTTCGCCGTAGCGCAGTCCGAAAACTGACAGACATAGTGCATTAGCATTTAAACCACCTCGAATAAGATTTGGGCAGATAATAGCGCCATCGTGTGCACTTGTTGCTCGGTGCCACCTAACCCCGAAGCTCCTAAGGCGCGGGCCTATAATCGTTATCCCCTACGAAATGCAAGTGCGTCCTTGCTAGAATCATTTGACTCTCCAGGGCCGGGAGTGATAGACCTTTTCAGATGTGTACCCAACGATGGGTTCCTACTCACGTAGATACCAGTTCAACCGCATAACCGTGAATTTTGGTCCGTGTCGTGGACGCCCGGAATGATAAGCCTCAACAGATTGCCTGTTTAGCTGGTCGATTGTGCCGATCAAGTTGACGTGCTAGGCCGGCGCTAAGCGTAGAGGAGAAATCTCGCAGCTTCGATACACGCGAGAACTTGGGCGTCACTTACATAGTCGGAGGTGTCATGGTTGAGCCGGTATCTCCGATTGATCACTCGGGACCAAACTCTATCTTCCTTCTAGAATCATCACGCCGACTTGAACACTGTCGTCGTTTATCACTGATAACGCTTATCAGGTTACGTGGAATCGAAGGTTCAAGACGGTCATGGAGCTGTTTTCTATTATTTCACTGTTAGTTCTTGGATACTGGCGAAGGACGCGCCACTTAGACTGTGCAGTCCCCAATTGGCTCGAGATTCCATCGGCGCGTCTACCTGACTCAATGCGTTACAGTCTTGGCCTGGCGCTCCTACCCCTGCGGCCTATAACGAGGTGGCTGTCCCGCGTGCAACACTCGCGAGCAACATGCCAAGACTTAGGTATAATAGCTTAAAGGTGTTCGCTTCTTGGTAGATAATTCTGGATCCGCGTGCCCACCTCCCTGTGCTACGAAGTTCCGTGAACAATGTCTAGATGTATAGCAGTGTGCAAGCCACCAGGTTCTATGGTGAGCAGCAATACAAGCCGTAGGTGACGTTCGGAATGACCCGCAATTTGTCGCGCCCCAGAGTAAAGCGAAGGCTTGACACTCCCGACTAGTAATCCCATGTGTAGGCCCCAGCACTAAAACATCTCGTTCCTCCTCACTTCCTGTGCTCAAGCCGCCTGGGGTCGAGGCGTAAGTACGGTCTTGATTGGTTGATTTTTGGACAATATGATGTCTCTACCAGCAACGCCGCCACCGGTTATGTCAGTCTCTGAGTTATAGCTACAATCTCAAGAATGTCGTGCGGCTCCCGTGGATGGCAGACGAGTCAAGACCAATAACAGACGTGTGGCACCTCTGGTCGTATCGTCACCCCCAATTGATGAAAATGTGGCTAGAGTTCCGAGGAGGACTTGCAAAACGAGTATCATTGATCCAGCCCATTACTCCAGTGTCCAAGCCCGAAACTGTAAGAGGGCCATTGAAATAATACCGGCTAAGGAATGTCTCGGGCGTGCGGGAATCATAAGGATCCCTCAGTTGACGATTGGGCGCCTCTTTTGCGAGCGGCATCCGCTGCATCGAGGTAAATATGTGTTGGGGACACAAGCCGGATTGGCATTGCCGGAACTTATGTGCGGCAATTGCAAAAGTCGAGTACTAGAAGGATGATCAATTGCCGATGCGCCAATTGAAGATGATCGCCTAAATTGGCTTGTTCATCCTTCGCTCCTGTACGAAGAACTCTATCCAACAGTTGATGGTTGGCAGTAGTTCCGCACGAACAACAACGGGATGGAATTCACGGACATGTTGGTGCCTAAACTAGCGCCGGTTTACCGGACGTGTCCGTACTCATTCCCGCCGCGCCAGCCAGAAAGGGTCGATAATTGCAACCTCTCTCGCAGTATCCTTTGGTCGGCAGAACGCCATGGAGCGATCTCCTATCTCTCAAGGTCAGTTTAAGAATTATGAAGTACTTCTCGACGTGTTGAACTTCCGGTCTCGGCCGTTAGGCTCGCTCGATTGAAGTACAACAGAATTCAGTTTAACCTACTACTCGCCCCAGAGTACTTCCTATGAATGGCTGAACTCTGACACCGAGTAGACAAGTGGTGGATATACTCTTTACGGGAGTCACGTATATCGTACTATTATGTTTCAACGGTGCTTGCCATCCACCACAACACCGGTAAGATTATCAACGCTTACTCTCAATATTGCCCGCGAGGAGGTCTTATCCAAGGTGTAACAATAGTAGTCTGTAGCGTTGAGATTAGTCTTAGAAACGGTGAAGGGCGTTCTCGTGCGCTCGATACCGCTCCCCCCCAATCGTGTTCGGCATCACTAGGACATACAGCGGTCGCCAAAGCCTTTCACCGGTATCGCTTCTCGGGACTGATGCTGCAATACACGCGTAGTCGAAGCAAATTTATGGTGCCCAGCATCTGAAGCAACTCCATAACTTTTACCGTCGATAACAGGATTTGGTAGTCCGCTCGGTACTAATGCCGCAAAATGAAGCCCTATAATGAGATATCCTAAGGACGTAGGGCGCCATTGTTGGTTAATTCCCCCTACGGATTGACGGGCCGCGCCGTCGGGCTGGGGTTCGTATGAACCTAGCTCCACGCCAAGACCTGTCCCTTGTCATAGCCAACAGGACACCTTTCATTATGGCGCTACGCATATGCGACTGTTCCCACAGTACAATGATGTGCTTAACCATCGTCGCTCGGCGATAGGGTATCTTTTAACTATCTTAGACTGATAACGTGTGGGCCGATAGTATCTAAGAGCTGTGAGGCTTGTGGACCACTTAAGCTATCGACTCCCATTGGGGCAAGTGATTACCCGGGTGCTATCCACAAGACCGCACTTGTGTCCTTGCGTCGAATTAAGAAAGCTATAGGGACCAGCTGATATTAGGTGCTGAGGAGTGCTACCGGCCTGTTTCACATATATCAGAACGCGTGCCCTGAACTAAGACTCAGCCAATCAATACTGCGTTGTGGGTGAGGCAAGTATTCTGTCCGGGGATGCTGTGGGGGACAGTATTGATCTATCATACTAACCATAGTCGACATCTCAGGTTTTCGAGCGCTGACGGTACAGACAAATTTAGGGCGCTACGAGAACAGCATGTCGCTTGAACCGACTCAGGCGCCGTAATTAAAGGGAGTGTGCCATGAACTCGAACGCACTCCGTATCAACGCAGAAACCGCCTTACAACACTGAGCGGCGTAAGAATACTCACTCGATATTGATTACCGTAAGGCTATATTTGTATGGGAAGCAAACGAATGACATTTCCTGGATATACAACAGTTAGCTGAAGGCATATGTGATCTGCCAGATTCCAGAAGCTGATGGGGGATCAGGATGAACCTTGTCAAGGATTCGTATCTGCGCTATACAGGGAGAACTGTGCGATTGTTGAGGCTACGCCGCGTAGCCGAGCCGTTGGAATAAGCAGCCCCGTATGTGGACATTGGTAGGAGCATATTCAACGGGCCACTAAAGGTCGCAATTGCCTACATCAGATGAAAGGTTGTTACCGGGCTAATATCATATAGAGCCCTCTAATATCCACCTGTTGTATGAATACTGTCGCAGTTTCATCACGGTTGCCCCTAAAACACTGACAATTAGGTAGCGGTATCGTTTCTCATCTACTCAAGGCGTATCTTGGGTCGCAGGGGCACGCCGTGGTTGCTCGCCAGTTACTTACTGACGGTACCTCTCATTCTTTGCAATGCGGGTACTTGTGTCGTTGAAAGTAGTGGTACTCGCACCAACTCAATCTATCGCCGCTGCGAGACAGTCCCCGAAAGCCTCCGCAGGAGCAGCGCTACCTCATATCCTGCACGATTAGAATTAACTGCCTCTCTAGAAACGAGTCTTACTAGTAGTTGACCTTGATTCTACGGCCACTCGCATCGCGATGATTGAGAGAGTTCCCCCACTCACGAATTAGGAATCATGTTGTAACAGCGGTCCCACTTGAAGGTGAGTCTCCATACAACGAGTACATACTTGAGCAAGCAACTAGATTATCAAGAACACGCATTTGTCCTAGCCTGAACCACTTTTGGTCTCACATAAGACAGCGGGAGAAGCGATTCGGGCGACGAGGCTGTTAAGTCGCACGGGTTGCTATTCATATAACACCTCGCCGTCGTGTTAATGATGTTTATGAGCCCTGGCGGTATGCAGAGCTAATTGGTTTGCATGGGTGAGGTAACTTGATTCCGTGTTTGGTAACGAGCGGCGGTCTACACCTAGTCTCGGCCATTGGAGACTGTTCGCGGGGGTAAAAAATCAATTATACAGACACTCTAGCCTGATATTGCCCAATTTGAAAGAGTTCAACCTTTCGCAGTTTAGTGAAAACTGAGCGGTTTGTGAATATTACCGGCCTTATATATCAAATGGTCCGGTACCAAGCCTAGACATGTTCGGACTTTGTTCCGTTAAAACCGAAGATTACGCATTTCACGACTCTAATTTTTAGAGACTGCTAGACAGGATATCAGCCACGGTGCGTCCTTCCTGTATCGCTACGTACTTGCTCCTCGCCTTCTATATAACGGTACTGGCGAATTCGACAATACCCTAATAGGAGCTGCGACTCTCTAGACGACCAGCATGCAGCTTATTTAAGTCACACAGATCGTAAGAGAGCCTCGCAATGCTCAGGATATCGGCTGCCCTAGAGGATTAGCGGGAGTTGGCTGGCGCTATTGAATGTGTCAGCAATGGCAGCTCCAGGATCGTCCAAGGAGCCGCTGGCCCGTCCCATATGGTCTTCGTATCAGTACTGATCAAAAGGCGCAGCGTGAATACGTTTTCCTCCATAACATCCAGTCAGTAGCTGATAACGTTCTCACCCACTGACTTCCAACAGGGGCGATGGACCTCCAGGCGAGCCATGGAGTTCGACCCCCTTGAGGTATAGTGTAGGAACGGGATAGGGATTAAAAGCGTTGTGGTTTACTCTAAGCAGGCTAAGAGGCATAATGTCAGCCCATCAGCGCGCGGTTAGACCTAGCCGATTGGCGCGTACCAGGAAGCCGTCCGTCAATTTACAATTGGTCGTAGTCGGGATACCATCTTGAAATGCGTAGTCCGTCGCGCTTCGGGGCGGGCTTGAAGTGATCATGTGCACCCTTTAAAGCCATAGCCATACAACGTACCTCGGCTGAGTAGGTTCATTCTCTTGGAAAAATACCGCTAAGATAGAGACACCTAAAGTAGGCTTCTTAATAGGGCATGTGTTTCCGCCTAGCGTTGACAGCATGTGATTAACCACTTGACCATCTGTCACGCGTCATGCTGAAGCTTACCCTTGATACACGGGCCGTTATCCAGACGCCTGGAAACTCGAATTCATCAAAATTCCTCCATTTCTCTGGCCCGACAATCCACTGTAGAGTGGGATCGGTGTAATACCCTGAGTTTTCTAAACGGCGACACCGATGCTATTTAGTATGCCACGCGCTTCGTACTGTTGAAAAGCAATTGGAACTGGATGTCTATCCCGTACTTTTAAGTCGTAGATCCGCATCATCCATGCTAATCGTCGTCATTAACCAATCACAGTCTTGCAAAACTCACACTGGCTGATTCTGTCCAGCGTTACCGCGGTCCTGTCCGATTAAGAGCTCTCTCTGCCTATTTTCAGTTCCCTCCAGGCGTAAGGGACTTGATGTACACGCTCGACGAGTGCGGCTCTCTGTGACTAGAAGTCACTCGGGCTAAAGACGACTAGAGGTTTTTTCTGCGATCTAATATTAACCATACCCTACACAAACGCCCACCGGTTTTTATCACAACCACAGTAGCGGAGACGTAAATCGTTGTGCACAGAAAGTTAGGTAAGTTATCAAAGGGCAAAAGAATTACAGGCCATATTCTTTCAGTGTGACCTTCGAGTGCGGATTAAGTCCGCGGCAAAAGCCTAGGGACGACATCTTAGTAGGCTATCTCCACCCAGTATCTGGCGCGACGTCAGGTGTCAGTACCATGCTCTTATGCCCCCCTTTAGGTCCACCTAAACCTCGAGGTCAGCGATTGACCCATGTAGATACTGGTAGACGTCGGTGCCACTATGATCGGTTTTGTCGTAATTCACGAGCATTTGTCATACTGTTAAAAACAAACTTTGACGACAGTTTGGTGCTAATTTGAGAACCCACGTGGGGCCTGCCGCCGGATGTACGGTATGATCTCACCGGGTCTCCATGATACCCCCATCAGCCTCATGTTCTGGCCCGTCCTCAGAAGCGAGCCCTCAGTCCTTTCTTAATCTCCAGTTACTTATCAGGGAGTCCAGAAGCTCCGGGTCTTCCAAATCCTCCGCGATGTCTTAGTCGACCCTAGGGACACCTAGAGGATAGTCGCATTTGTAGTGTAGCTGTCCGAGAGCAGAACGCTGCGGCAGGCGGACATTGAAGTTACGGCTATGTTATCAGTCATCCTCGGCTTATAAGAGGCTTTGGGAAAGTTGGGTTAGTGGCCCAAACGATGATATGCACCAACCAAACTCTTTCACAGCAATCCCGCAGAATAATTGCGGCGCGGACGGGCGATGGGCCAGCTGCTAGGGTAGCGACAAAAGGACCACCAGCTTCTGTCTGAAGACAGGGGCCACCAAACCACCCTTGTCCAACTCGTATGCCCGAACAAGAATCGAGATCGAATTGTCACTTATCATCCCGTACACAGTAGGTCCCGTCTACGTATTCCATGCGTTGCCGCAGGATTTACACCAAGTTTGGTCGCCGGTCCTCACTCGCTAACTACAGCTGTGTAAAGCGCGGGCGAGGGCGATGGATACGTACCCGAGGTTATCAGGCTGAATTGCTGGTGAACACTTAGGTACGACTCATACGCGGGAACCCGGCAGAACTGTACATTCGCGGTTTTTGTCCTCTAGCTATTTCCAAGAGCTGATCACGAGAAGTCTCTCCACGCACATCGCTGAAGCGAGACCCTCGCCAAGTGTTACTTATAGACTTCTATGCGGCGCCGCAGTTTATACAAGTCCTCGCTCATTTTAGTTCGTGCCTACACTGTCACTCCTACGGTACGCCACGGCGCGTGGTGATGAAAAGGTTTCAAGTTCGTATGCGAAAATACAGGCCATTTAACACGGACTCCGCGTCCGGGCGGGGCCGTAACGTTGCCCGTACCCGGACAGTTCCATTGTGAAGCACTACAGCTTCAATGTTACCAGTGTAACGCCAGCATCAAGAGTTGCAATGGTCTAAGCGTCACCTGAATTTGCTATATCCTGACGAGACAGGCGTGCCCCATCGGAATGGCAGAGGTAATAGGCAGCATCCCCGCGGATCTTCATCTGCCGTCAACAGCGCCGGATTTGTAGGCGGGGCGATAAGCACTCGGGGGTCATCGTTTAACCACCAAATGGGCAGTACAGGTGTTCTCCTGTCGGGCCGTGTAGTTAGTCCGACAGGTGAAACAATCTGTCAACGAATTGGCGCCTACTTGGTCCGCCAAGTGAGATCTTGAAATTACAAGTCTTTCCGGCGCAATCAGGCCACGATACTGGGGCAACACCCCGTTGGGACGACTGGTAGAAGCTGGACTCCGGGACGGGGCACAAGGCGGTGGCGGCATTGAACAAGCACGCACGCTCCTCCCTATACCTACGACAACTTAATCTTGTACCAGACAACCTAGGAACCCTCACTTGACTGCTCAAGCCGAAGGGAACAACCCCCTCCTTGGACAAAGCTTACTGCCAAGGCTTGGTACGTTCGCGTGTCCGTTCTGTATCGGGACCTGAATTGCGTGTGCAAGCGTCATTCGCCATGGCCACTACGGCCTGGTCGGGCACCCAGTGTGATAGTCTTTCATGCGAATGGCCCAGTGCTATCTTGTTCGCAACGTTCTGTAGATAGAAGGCCGTGGAAACTGCGACTATCCGCCGCACAACCTTCACGGGCCCCGCCTCTCTATGGAATACGTGTCTCATGTGCGATATGAAGGTTGCCCTCCATAAAGCAGATAGTGCTGATGTGCACTACTTGGTACTTTGAAACGTATTAGTCTCACCTGCTGATGATTCCTTTAAAGCGGTGCAAACAGCCTTCGGCAACCGGCCACTTAGGCTCGACGGACACCATGCCTTTCTGACTTACAAAATGACCACGCCCCTACGACAGCTGTCGTTACCAGGCATGCCTTAGCTGTCAATGGCCTCATCCTGCCTCCTAAGGGGGTATGTTCTCCTAGTAGCCATGTCATAAAACCCCTGCGCGAACCGGGTTATCTACGAACAGTACGAACCCGGCGCGTTTTGGCTAAAGTGGGGTTTATTCAGGGAGCCCGACATACCACAACAGTAACAATAACACACTAGCCGTTAGCAGGGTCGACGTGCTCCCGTTCGCGGAATTCTGGCTGAACGTAAATACGCACCTGAGCGAATTTTCCACGAACACTTTTACATTTAACCTCGCAAGAACCCTCCCCATTAACGAGCTGAAACGCTTATAAGAGAGACGTAATGGATCAGAGACCATCTCCTCCGAGAAAAGTCTGGGTGAATCTACGATGGGTATCTGGAACCATGCTCCCTCTTCCGGAGGACAAGCCCTTAATATGGAATCCAGACTAAAGCCATAGCGATAGCAGCTTAAAACTAAGGCACGTCGTCCAGCCAATTCGGCCGATTCCGTTTGGAACAAATAGCTGTCTGTCGCAAACACGACCCTGGGAAATGATCCAGTTCTACCGCACCAGAAGCGACCCACCCCGTATTCGCGTGGTGTTCCTTCAAAAACGCCCCCTTGGGACTCAAGACGTCGAACTTCTTTACCCCAACCGTTGCGGGGTGTGTGAGAAACCGCAGACTTGAGAGCCCGAGTATCTAATGCAATCTTCTCGGGTAACAAGTGTGTGTACATCGTGACAAGTCCTTGGGGTCTGCAACAGTATGTCCGACCAATTGACCGACCGCAGCATAGTCACAGTCGGAACTTTCGGAGTAAATCCAGGAGGGACGCCTATAAACTGTTCATAGGTGTCAAAACGGGCAAGGAACCAGAGAATGATTCAGTGCATTCGAAGAGTGGACGCGGTAACGACGTATAAATTTCGCGCTTCCAAGTAACACCGGACCGCGATGTGTGTCGCATACCGAGTTCTATGACGATGCTCAGAACCTTTGTCCACTAGCTTGCAGTTGCTCGACCCTAAGCGTTGATCCGATCTGTGTACAGAGAATCCACTTCTTATCTCCGTTGGCCATTAAAGCGTTTGTGTCCAGATCGGACTTGGTGTGTATGTAAGGCCTGATACCGCACAATAGGAAATATATCGGCTAAATTAAATTGGCTCGGGATAGCCGATCTCGAATACGTCCATTACTGAAGCAATTGGTTACGCGCGAGCCCCCGATATTGACTTTGATAGTATGTCCAAACGAGTACAAACTCGTTGCACTTAAGTTCGACTTGCTATGAAACATAGCCGTAGGAGGATTTAACCGAGCCACAGGCGGCTCCCTCTATCTTAGCGGATCGAAGTAATATTCTGTTGTCATGGCTTTAATTGGGAAATGGCTGCCGAAATTTGGCGAAAGATAACAAGTTAATAAGGACAATTCCTACTTACCAAGGGTACTGTTTCGCAGCGGCCGGTACCCCTTCGAGACTCTGTTGATTTTCCGTGTACACAGGCAAAATGCATTGTATATCCCGGATTGCTTGCTGCTCATTAGGACTTTACGACATTAAAAGCAGACCAATTTGACCCTGCTAACCATTAATCAAGGTAAGCTGCTCTTTCACGGAGAAAGCGCGTGTCTGACTGAGTATATCTAATAGAGTTAGCGTACAGTAGTGATTGGCATGCCATCGAGAGGCGACGTCCGTAGTCAACCTACACCGTTAGAGAACCCTTGTCCGTTGCGCTTCTTAATCTTTTGTCGAAGAGGAAGTACATGAAACAATCAGATTAGTCATTATGATACACATCGGTTGGGACACATAATCTTTGCGCTGCAATACCCTACAGTGGCTGAAAGAGTGGCGTTGCACGCGGACTAGGATTACAGCGTATGCCCAGGTTCTTCGTACGTTCCTATGGGGCTGTAACTTAGTATCAGACAAGCTTGCAGACCCGCGCCCGGGCACCGTGCTATCTGAGTGCATGCCGTCGGCGTAAATCGTGCAGTGATTCTCCTCCGCCAACGGCCCTGAACAGGGTTCGGTGCTACTACTGTGGCAGGGGGGCGGGGTGTATGTTACCACAGAAACTCCTCACGCGGCAGGGTTGACGGCCAGTATACGCTATGAAAGCCAACAATTGGAGTATGAATCCCTCACGAGGCTTAGCGATGCAGAAGCTCGCCTGTAGACTAGTCTTACTAAGTGAAGAAACGGCGGACGAAATCGAACGTGGGTTATGCTTCGATAGTCAACCATGAGTGCATTCAGTAGAAGGTCGGAGAATCCACTAGTGTGCGGAATTATGGGTTCCATCTAAGGCGAGAAGGGTCCGGGTTAAGTCCAGCTTCTACACTCAGCAGGCAAACATACGTGGCCAGGCTCCTTTTAATCCCCGGAACAACCCACTCCGGGGGGTGATCCCGAAAGATAGATTTATGTTGAACAGGCAGTAGCGATTAAGGCAGCGGGAGTGGACATATATAGCAGCAAATTGTCTCCCTCGGGCCTTAGCTCTAGCTCCGGATAACATAACATACCTGTGCATTTGGCAGCAATGATGATCTTGTGCTAGGTTGACACTGGTTGGCGGACAACGCCCAGTAATGGGACTAGCCTGTGGCAGTTTGAGTTTATGCGTGAGCACAGAAGCGCGCCCGTCTTAGGTTGCTTCACACGGCCGATGTCACGGCAAATTGGTTTCCAGGGAGAGATTGACGTGTCTTGAGTCTACGCTCCGCGTTAAATACACCCCCCCTGACCACGTTATTGTGCGTTTAGACCTATTCAGTTCAAGGCGTATGGGAAGACAGCCCGGTAACGTCGCGGTCGATGTCGAGATCCGCTGCGCCCGTTCATAGACGACAGCATGAGAATCGACGGTCTTGAACGTTAACAGATCTCAAAGTCGTTAGCATAAAGCTCCTAGACCAGTCCGTATTGCCGAATGTCCTTAGACTGATAGGCTATGGCTGCAGACTCACGCATCAGCCCGGCGGGGCTTCAGCGATCTAAAGCTCGCTCCGAAGAAGCTCGGGATACTCATGAAGGGAACTTGAAGAGTTATATCGAGCACGGAGAGACCACACATAGCCCTCTATAGATTTGTAAAATTAATGGGATTGTCATACATGCCAATGGTATGGGCTAGAGGCGCCTGTCAGTCAAGGAGATAATTCGTACTCCCTTACTTCAGGGTAGATCATGACAGTTCAGGTGAGGTCATCTAAGGAAGGTCGCTCGGCTGTAGGGGTCTCGTACTATTAGCCCACCTCAGCCCATCCGCCTTCACTCACATATTGTCCCCCTGGCCTAATGGAATGGAAGGTGATCACTCTGGTCGGGTACTACCACCATATAAACACTGTCGCTGTAATTGTGTTCACTAAATACGCAGTCGAACGTCCCCAGTCCACGTCCGGGTGATGCCGCGCTCCCAAGTGGAAGGTATCGATTTAGGAACCATCGATGCTAAAGACTGTATCCTCGTACGCAAGCTACCGGGAGACACCTCCGGGAGCAGTGTCGGTACGCTTGTATAACATCCTGACAAACGCGTTAGTTGAACATTAGGCGTGGTTCGCAAGGTCGGCACTCGCTGAGACAGTGTAAAGTTTGGCGGCTCGTTACCATGAGGCCTTTTCTTCTTGGGAGGTGTTAACCCAGGGCGTGTGCGTATACGCCATAGGACTTACTAAGTTGTGGACACCCGCCCGCCTTTTTAGTTTTAATAATGCCCGGCACCTTTGCTTATGCGATTGCAACATCGCTGCAATAAGCTCGCTGGACGTATCAGGCCGGAGAGATGCTATCGCGAAAGGATTCTTCCCTCGCAGCGCGTTCGCATTCTCATTTCGATAGAGCTCGATTAAATCACGGAACGCTATGGAACAAGTGTGCGGGACCGAGAGCAAAACGCACGTGTTAGCACCTTGACCTAAGAATTGGGGATAAGGATAGCCGAATGAATGCACTTAGATGCGTTTCGCCGCCTGCTACCACATGAGCTGAGACAATTAAGCGCAGAGATCATTGGTGCTGTCAGTGCAATACCTATGTGGGCCGCCTTACACTAATTAGACATCCGCAGCCGCCCATTTGCGGCACGAAGGGAAATCCGTTAAACACGGGCCGTCCGAAGTCCACAAGCACAGGTCCGTGACCCGTGATGGTTCTGTTTTAAGCCATCTTTTGGCGTTCTGTCGATGAAATGCTGAGGTTAAGTGCGCGAAGTTGCTTTCCGACGAGACTGCTCCCTGCCGGCGGGTACGCGTACAGACCCTGCGGTCCGCGGGCGTGATCTAGATTACAATCGACTTCCACGGCTATCATCCGCTCGTTTGCCATGGAGTCGTGACAACCAGTCTAATTGGGCTATATCCCCTGCGCGAGTACTCCGCGGCCATAGGTATGCGTTACAGCGTTCCGGAGCAAAGCGTGCACTAGTATCTTCATCCATGAGGTAGACGATAGGGGTGGGATCGACTCCGATGCTAATGTCTAAAGTCCCCACGCATCTATGTCCCATAACACATGACCTACAGACCTTCTGTTGTTAAGATGGTGTTTGTCCGATGAATCGTAAAGACTAGCTGACTGTACGCAAAACTAGGTAGTTTGCTATCTGACCATGGGGTTTGTCTCTGTCGCTTTCGAGGGAATAATTAAAATCCGGGATGCGGGTTTCAGGCCCACGTAAGGCATCCGACTATCTACCAGCATACACGAAATTCTAATGAGTTCAGATGCCGTCTAAACAGCTGATAGTGACTGCCATCCTAGAGGACTCGCTCTCTTCTTACCCATGAGGTACTGCGTCGGAGTTTACTGACCACCCCCGATCCAGCTAGAGCGATGAAAATTAAGTTTTACGGACCATAGATGGGGTGTATACATTTACAGCAAACAATCGCCCTTGCTCCTAGAGTTACATACACGCCTCTACGACCTGCCAGCCAGATCTCGTTATCGCCCAAGGCAAAACTTACCGCAACGCGAGGCGCCTTTGGGACGGCTGCCTCATATAGCCGCCATACACATGACTACCCAGCGACGTTTGTAGAAGCAATGGGCGAAGAAGGACGATTCGAACACTATCAGGGGTGCTTCAGTTTACCTGGAAACGACTTTCTCTGCGATCCTATTCACGTCCTAAAGCATCTCCGCTAACTCGACGTTGAGATGAGCCATTGGGCTGGAACAACAGTCAGCCCCTAATGAGGCTACCTCGACCAGTTTTGGTTGCAAAAATCCGCCCCCGGCTCTCCTTACAATTTGCGGTCGCTTAGAGACATCATTATTCACGGTCGCCAGGATACTATCCGTACGAGACCTATGCGTAGATTTAAGACCCGGCATTCGTTTTTCCGGTGTATAATGATTCAGTTATTACCATCCACATCTAACATCAAGAAAACCAGCAGGCGTGATCATGCTTTAGGTGGGTCCAGAGGATGACGACAGGCTCTTGCTTATATCCGTTCACTACTGAGGTCCCGGGGACCCACATAAGGAGCATTGGGCAAAATACGATTGCAGAAGGCCGCAGCTGTGCTACCAATTCTTGCCTTCCGTGTTTCCCTATCACTAAGACACCGCAAAGTCCATCAGGTCGAGTCATCCCCAGCCGGCAAGCAGATTCAGGTAACTACACAACCTCACTGAGCAGCGACGGCTTATAAAAGTGCGTTTGTTAACTTAGGTCTTTAGCTATAACACGTGGCTGATCACACTCATTCATGTATCATCGGCGCTAATGCGGCAAGTGGGAAGACATCTAACCGAGGGTAAGAGTTCTATCTTAGATCCGGTATCGTCAATACTGACGCGAAGTTGCGGACCATTGGAGTGCGCGCCCTCTGGCTGTTTGGGGTATTTCATCTCTGAACATTTAAACATGTAAGAGGTTGAACGATCATGACTCCAACCACCTTCGCCCAATTCGAACAAGTTGACGGCTGTGTGAGACCCGCTCATAATACCAATAAAGAAGGTCACAAAGCTTAGTGCACGTTTGATGTGAGCCCAGCCCGCTAGAGGCCTGCTAAAACCTGCAGCTGACAGGGGCGCCAAGACGCGAATCTGTTGTATTACAAATCAAAGAAACCGACACATTTTAGACTACGAGCCAATTACGATATCGGGCCCCCTTCCCGCCGAAGAGTTTGTCAGTCACATAATGATCGTATGTCACCGATACCCCTGGAGGGTCCAAATATAAAGAACAGTCATTTGTAATCTGGGAAGTCACAACATTTATGACAGGAGATAAGGTTATACAGCCTTGTAAGACTCGGATGATAATATTCGCTCTATTGACTGGCAAGTATTGCACTATTTGCGAATTAAGAAACACCCGCGTCCCAGCTCGACATTCCCGAGTGTTCATTCCTGGTCCCATCTTGACCGGGTATGGACTGGGTCCCTCGATGAGCACCTGTTCGCTATCATGTGGGCCGATACATCACACACCCTGATCAGGGGAGTGCCGAATTTGCACCGTCCCTGTGGCATGAAGTCTGGTGCACCGGTTACAGGGATAGCCATTGAATTCAGGGCCTCAATGTAACCAGTAAGAGCAGTGGGAAAATGCTGATGAGTTCGGATGTGGTTGTAGTCGACAGAGTACCGCGCATACTGCTTCTTGAAACGTCCGCGAGGGGATATTCGGCTTGTCGGATTATGGAATGGGATCTCATAAATCTTGAACAACGAAACACTACATGCGTCCCGACCGTGCCAAGTCATCTATTTAGAGTGCGCTTAATATATCGTAAGTAAGTCTGCAACTGTTCCGGCCGTACTTCTTTGTGGTTCCTCACAAGTATGAACCTTGTGCTCTATTCCACCGGAAGCTGGTGACTGCAATCAGAAATCGACCTGTTCTCGTTGACTGCACCGGCTGACGCTTTCATACTCTTATACGGACGAATGAATTTCTAGTTAAAGCCGCGACTTTTTAGGAACAGAGGCACCGGTTGTATCTTCGCCCGGAAATATTGGCAGCTTTTGTTGCGTAGTTATGGCCATACTAATACCGCCTCATTAGTCTATATTGTTTGGGCACATATATCATCACGCGTACCCGCCCAGTACTAACCATCAATGGCCTCTACGAGACAGTAACATTTTAAGACCCTTAGGCGACTCAAGAACTTCTCAGCAGGGTTCTCGCGAGATCATAATCTATTGCGGTTTCGTTAGCCATAGCAGCATCTTGTATTGTTATCATGTCAGGTATGCGCTCTTGTGAGTCTGACGAGTGGTCTTGTTAGTCGTTTCCACCGCTCGATGCGAGTGAGTGCAGACCGCTTCATGTTCTTCGGTTGCTCGGAATGGAATGGGGCACGCAGGCGACAGCCTACCGTCCTGCCTGGCGAGGGAAGATTTCAAAGTCGCTACCCGATCTGGGTTGTTTCTTAGTCGGCATATTGGAGGCGACTCATAGAACGTTACTTCAAACATGGGATTTCATAGTTGTTTTAGAGCCGCAAGTCTTACCACACGATTGCATAACTTGATCGTATTGCGAAGTTTGAGTCCGGGAAAAACAAACCTCTAATGATAACACATGTCTGCCGGACCGCCTTGCAGTTATCACCGATCCGGTTCATAGGGTAGCCAGCTTCGTATGACCTTAGCCGATTACTGTAGAGGCAATTGCAAAGTCAAAGCGAAATTCAGGCGTACCTCAGACATAAACGGGAACCTCGTCAGCAAGATCGGTAGACCTAGGCTACTCACGCAACGCGGTATATGCCCGGTTACTACGCGACCACGTGATGTAACCTGCTGTGTTTTACCTGGATTGCCATCGCTGGCAGATAAGTATACTAGTGATCGTGTATTCAGCATTAGGTTATTTAGAGAGAACCATCCACGTCAGGTTATTGTTGTTAACATCGTGTCGGGCTCCATCAGAGATATCCGATCTACCCTGTCAAACAACGCGAACACGAGACAACTTTTTGCGGCGCCATTTGGCCGCCAGCCGCAGGCCCCCAACGTGGTCTTACCATGAAGGGGAAGCACTTGGACGTGAAAACTGAGGTCGATTTAAGTTTGACATACAGGACTCTACGATGACCGTCGGGTGACCAATAAGGATCTACATCTCTATTCTTCGTAAGCACTGATGGTAGTATTCCAGTAATGGGAAGCTCGCAGCCACTTTGATGCTCGTTTGATAAACCCATATCGACCAAGAGCCGGCGGAGTGGCGGTTTGCTTATCAAATTCATACAGCCTGAATTTGGTTATCAGATGCCTAGCCCCTGAAACTGCAGCTCAAGCCACTGACTACAGAACTGCCCGTTTCGCCGACATCAACCCAATCGAAAGCACGATGAATCTATCGGTAAACTCATCTGTGGATCCAAACAGCATCGTTGGCCAGTACGATTTTTGCATCCCCTAGGACAGGCGGGTCCCTAGTCCGCTTGGGGCCACAGCTTGAAGGATTAGAACAAGTCGTGAGGATAGTGTTCTGTACTTTACTATAAGTATTTCGAAACTATCCATCCGTTGAGTTGACTCACGTTCGCCATGGGTTGAAGATGGACCTTCAATGGTCCAGTGTGCGCAAACAACCAGTAAACGTATTATCGTATCGAGGCAAGCGACTCATCACGAGCGCCTCGTTGGGATCGCAGAAGGGACGTAGCTGGTCACCCCAGCTATTAGGCCTGCATTGACTGCCCGCGTCATAATTCGTGCGACAGTCTATCCCGGTACTCAGCTCTACGTTATGTCTACTAGATACTCGGCTCTTGAACACCTTCCGGGCAGGACCGGAATCCCTGTTCCAGTGCACGATAAGAAGAGTTTTCGCTTCACTGCAATAAGCCGTCGATTACACAGTGAATGTAAAAAGAATGCTGGCCATGAAAGCATTGTACAACCATGCCCAGGAGGGTCTCGGACTCTCTTTCGGACAACCGCACTGGCCTTTAGAGCTGGAGCGCGGGTAAATTTCGAGGGGGTCGACTTTTTCGGGTGATTCCATATAGGCGATGTGAGACACGGAACATAATCTGTCACGATGGATGTGCCCCATGACGACCGTTGACGTACGACAACTCGAATTCAAGGAGAGTAACGAAGCGTCCGATATAAAGTCCCAACGTCTTCCGAGATCAGACCCAACTAGAGGATAATATTGTGCCAATAAAGACAGGCAAGCACTGTGGGGTCGTCAGTTTTGAGCCTAGCGTATCGGCAGAAGCTCGCAAATAAAGTCACTGACGCACATCGGGTAACGTGGTGTCCCACTGGATTTAGCATTGCAAACGGCTCAGAGCGCGGGATATCGGTGTTCTCGACTCCGAATGTATTGAGTGCGCCGAGTCGCCTCGTTATTCCGGCTTGAGTCGCTCTCTTCTGGGATATGAGAGAATGCTTTCAGCCTCTGACATCCGCCGCGCATGAGAGAGAGATGGAGATAATAGGGTGTTGGCATTCGGGAAGGGCGCTCAATGCCTACCTCGTTCCCCTCATGGTTCCCGCCTTAACTTGAGGAAAGATGGCCAGTGTACTCGGACCCCCATGGAAGATTGGTTTCCATAGATTCCAGCAGACCTAAACGCTATCTGTTCTAGCACGTAGGTCGGAAAAATAACGGCCGTAATTGGTTTTTTTCCCAATATTACAGCCCTTCCAGAATTACATATCGTCACCAACTAGGAATACAAAATCGAGCCAGATTCCCAAGCGCTCCCATATCTTTATGGTGCATTGATATAGCCAAACCCTGGTAGAGAAAGGGTGGGCGTACATCGTCAACTCTTCTGAGTAAAGTCTCAATTGAAGTGTCTTACAAAACGATCCGATATCGACTAGCTGTCTCTGTTCCTTCGGTGCCCAATAGACATTGACAAGCTGTGAAATGTTGGTTGCACTAACTTTGGGAAGCTGCTACAAATGGCATAACGATTACGACCGACGGGCTCTATTCCCTTTTGCCCCATCCTACTCTGTTATCTCGCAAATCCCAGATGTGCGACCTCCTAAACAGACAGAGTGGTGTTCCCGCGATCTGCTAGAAGCAGAGTGGTCTGGGTACGACGTACCTTCCTCGCGGAAAGTTAACGGGAGGGTTACCCTCCTGATTAAGCTCCGCGCCCTCCATCACGACTCCGATGGCCCGTTCAAACGACCCACTCGATATAACAGGACTAAGCCACCGCGCAGGGACCGCTTGACCTATCGCCAGCCCGTTGCTGGGGGAGCCTTGCTTTGCAAAATTAAGCCCCGAACCGGACATTTGCGGTCATTGCAAGGGCAGATCTACTCGTAAAGTTTCCCAGTATCGAATAGCTACGAGTAAACGGAAGCATAAACGCATCAGTTATTCCGGGAAGCTCTCTTTAACGTTGCTATCTCGGTATTAAACTCATTTTTGCCTCCGTCACTTGACCCCACCGGAGACAAAAGGAAGCGCGCTCTAGGCGAGGTATCTACTCGTAACCGCATCCACCCGAGCGTGGGTATTTGGCCTTGGTAAGGAATCTATCGATCATCTGACACGCTACTCCGGCTCTAAATAGCTTCGTTACGGGGACTATTCACAAATCACTGGAACCCATCTTTGTAAAATTGGGGGGCTGGGGCCATACTCAGTAACTAGGCGGTTTCGTTATCCACAGTAAGCTAGCTTGCCCCTTCAGTACAAGATTCAGCACTCTATGTCTCATTGCGGGTGCGGTCCTGAATGACTGTATTTCTCCAAAAGTCCTCTGAAGCGTCATCATCGTCAAGCTCCTTATCCTCTCTAATTGTCAATATTCAGATGTTGCGTCCATCGGAGCTCGGTATGGCGTGATAATACCAGAAACGTGTTAAATGAATGCTGACGGAAGCCGTTCGACCATTCCCCGAGAGTGCATGGTCGTGTGGCGACAGATCCTTCATTTACGCTACACTTTTGGCGGTTAGACCTCACCTTCCAGGTGTGTCGTGCGCATCATTCGGCGCAAATGACAGGTTTTGCCGACTTGACGCCCTATCCGTGGCACCCCCCTACCTTCGTGAGCGTTGGCCCTGCGGCACTTCCCCAAACCCTGTACATCGTGGGAGATCAGAGACACTCATAAGTACTAGCGTTGGAAGAACCGGTGTTGGCGGGTGTCAGCTCTCTCTGTATCACATACTCTGAAGTCCTACCAAGAGGGACGCTGCCTACGCTACGCCCAGGTAAAGGCATTGGACTGCTTGTTTTGTTCGGCGTCGCCCATTCACTACATCGTACCCAACGGTCTAAATTGTTGGACCAATTTGTTCCACGGATGGGCGAGCTGCATCACCTCACAGCGGAACCCCTTCATAATTCGCGACCTTCCCGCAAGGTGAGGTATAAGGAAAAAACGGCATCCCGTGCAGTCGCGGACCGCCACTGGACAGGTTCTGAGTACTAGATGGGTGTGGCCGAGAAGATCCGGACTAAAAGTCGCCTCAATCATCCGTTACCAGTTTCTAAGTGTATACGTGAGCGACACATTAGCTCTGGGTTTCACCACCAGTCGAATGCGTCAATTCAAAATTGGCGTCCTCGAACACGCTTTACGAGCGATGCTCATCGCGACACTCCAGTCACTGTTAAAGGTGTTCCGTTAAGGCAAGAGCAGCTCCACATATAACGTCCATGACATGTTGCAAGCCTGCACCATACGTCCTTTTGGAGCCGTAACCTTTTCCGGAAAGAGGATTCAGGTCAGCATTTTAGGTCTCTATTAGTGACATTGCGGATTCGCTCCGTTAACTCAAGGCCATCATTTTGGGCACTCCTCGGAGGGACCTAATTTTACTCCTACTTGCGCGATATCGATTGACAAAAGGAATTGCGTCGTATTTTCCATTGATATAAAGTGTACTTACGGCCCTGACATATCCTCACGGACACGCCAACACCACCCCGCCGTTCACGTGCCCCCCCTCGGGCTACCAACTGCACAAGGGCACCACAGCTTGACATCCATCAGCATGTTTTTTCGACTATTCGGCCGGCACCAAGTTGACACCGCCGACTGACGCGTGGTCAGCCGATCAGAGGCACCAAAACGGGGTCGCATGCCTTAGACGAATAAGGGTGCCATCGATGTTGGGTATTATTACCGAAACATTCGGATTAATAGTTGAAATAAACCTCCTATTCCAGAGTACTTACCCTAGACCTCAAATAAGACCTGCGAGTGGATGGTCTTAACAATCGGGTGGTCGTGGTCCCGGTTTGGGATAGCGAAGGATAGGGCAAGAGGACGTCCAAGTCCAGTAAACTCCAAACAGCACGCTCACTCTAACAGGGCGGTGATAATGGGGTAGTTAGACGAGCACTCATCGAGCAGTACTTGCAACTGTCTTTCTCCAAGCGACGCTTGTCCCAATGGCATCCGTAGACGACGATGTGTCGGTCCGCCGTCAGGGGAATTATTCGTATGATGCCTCGAGTCGGTCTCGGGAACTTTTCTCGGTTTCCGGTTCCTAGGGTTGCATCCCTAGGTCCAATAATCATCTGTCGTGAAGGGGCGAGTCCTTCGGGGAGATGCTAATTTCTATTGGCCCCAACCAATTTTATGAAGTGTCGGGCGGCGATGTAGTAAAATTTATTTCTATACCATGAAGAGTGCTCAAAGACTGATCCAGGTTCTGTCAAGCTTTTTCTACTATCTATGAGACCCTAGCCCACTATGCACTGGATACGATAACGATGCTAAGGACTACGATGATGCGTGCGGGTATTTACGCTTTGTTGGTTACCATAACACCCACAACGGATCTCTTATGGTTCTTTGATACTTTAAGATCCTTACAATATATCAGACATGTCTACAAGCCCATTCGGTGAATTCTTTTCTCTCTGAAGAGGGTTTTGGCGTTCAACCGGGTATGCTGAAAAGCGACTAAAGTTAGCGCGAGAAACATTATAACACAAGCTCGCTGTCTTAGCAGGTCGGGCTATGCCCAGGAGGGGAACGATGATGGACACGTGTACTTGTGCGACCGGTCATGGACATATCTCTCCGTTGGAGCGTCCGTTCCCAAATGGAGAGAGACTGTGACAGTTATCTACAACTGCCGGTAGCCGTGCCCACTCCTACGGTACCGCTAGTCACAGGGATAGCAGGAAGTTAGTCCCAGTTAGCCATCACGCGGAAGTTATTGACCGTCTGAGTTATTGTTCCCATTATGAGCCTAGCTGAGATGAGTCTCAGCGCGGCTCCGCCTGTTGATTAAAATGTTTCCAGATTAGGTACTTCCATGAACTGATTTGCTCATACATTGACGGCGGGCGAGATGACTACGCTTGCCGACTACGTGGGCTCGGCTCACAAGCTGCGCGGAGTGATCGAAATCAAGTCAGTTGCACATAGCCTCACCCAGCACCCTTGACCGGAGCAAAAGTGCTGAATGACTGCCCGCGCAACAGCTCATGTCTAACTATAGGTCCAAGGAGACAACTTGGAGAACGTTCCTGCGCAATGCTCCCAAGGTAGCCATGTGCCAGGTAAACGCCTGCTAATCTAGTTAAGGTTACACACTAGAGGGGTCCCATTATTGCTCACGTGGGCCACGTGCTACACTTCGCCCATAGCGTACGGTCTTTCACTAGTTCCGGGTACCCACATTACGTACGTTCGTTCACTACTCGCTCAGTAGCTAAGATCGGGCTCTGGGGAGTTCCAATAGAGCCAGGTCCGAGCCATCAATTGTCTGACATATTTTAACTCTAGAACTAAAGCAGCCCAGGTGGGAAGGCCACAAAGGAGCAGCCGGAGACTATCAGATAAATACATACGCACCACTAGTCGTCATAAATAAAGGAGTTGTCCCCATGCTACTTAGGATTCAACGGCTGGTAACGGGACGACAAATAGGATTACGGTTCTGTCTTAGTAAGGCTTATTCTATGGAATGGGGACGTTGGGCCTTCAAGAACGTAAGGGAATGTCAAGTCCGGCTTGGTTTTTTCCTGATAGGCGTGATACGCGAGCTTTTGAGTGTAATAGCGGGAGTGTCTGTTGTTAGATTACTTTTTCCGTAGTATCTCACTCAAACTAAATTAACACCAGTAGGTATTATACGCGGAATCTTCCGCTTTTGACGTAGAGCATCCCGTGTCCAAACCGAATTGTCCTTTTTGGATCGCATGACATAAGGTTAAGAATTTACCACCACTCGTAGGGAAAGACCAAAGCGGGACAGACAACTGCCAGCGGGGCATAGCCTACTTCCTGTTATATCAAGCTCCAGCTGACTCAGAACCAGAGTCAGTAACGCCTATCTCTGACCTTTGGGTACTCCCACGCGGTATCATTGGCGACCAGCTTGTGGAGGATCCATTTAGCCACTCAACTTGTTTCTAGTAGAATTGAATAGACACTGGAGAGATGGCCAGCGACTGATCTTGTCATACACTTGTAGGTACTGTACCTAAGGTGGTTCAATCCTGGCTACGGGTAACAGTTGGTGAGGTGGGCCCTTCCTTGCGTTTGATGGGGGCAGCCTCGTTGGGACCGACTACCTAACCAGGTATGGTTTCCTCGCAAAGCATGGGCCGCCAGTATCAACTTGAATTCCCGGATTACGTAGCAGATTACTCCTGTAGTTCTTACACGCCCTCCTCTAGAGAGGAGCCGCCACATAGGGTACGCTCGTCCTGGGGATATTCACTATACGACTGTGTACTCCCTGGCACTGCGCAATAACCGGAAATAGGAACATGATAGCAAATCACAGGCATTGACCCCAGTGAACAATACCAACCTCAGAAAATGGGGGAACACCCTGCACCTCCGTGCTGCCTATAATACCTCATATCGTCGGCTCTCCATATGAGGGATAAAGATTCTTGTGCTTCGAATTTCAGACAGTCGACCAGTAGAGCAGAATAATAATCGTCGACCTGGTCAGTAAGGGGGCCGGCTAACGTAGACGTTCCCTCACGACCGCTCAACGTGTCTAGACAAGCACACAGCATATTCCGTCCGGATCCACCAGTGTATATTGGTAAGTTGCTCCCAACTGGTCAGGATGATCCTCGAAATTATTTTGGATAAATAGATACAATGCCTATCCACCCAGGTAACACCACTGGTACGCTATTTAACGCCTTCTCCCGGGTCGCTTAACTAAGTATGCTACACCCACATGCTTCAAATATGGTCGTTTCACCCTGTCGGTAGACTCGTCAGACCTTGTCTCATACCCAGTGATTTCAACCGACCAGTGGTGATATAGTAGACCCTGGCGGTAACGATGTATCCTTATTGACTCACCTCAACCCCCTGTTCACACACATTACGCCCCGTCCGGGGCGAGTAGTGCTGCCAGGATTTTGGGGATACAAAAGGTCTCTTCCTTAGCGGTGTAGGGGCGGATTTACCTGTTTCTCAGGTTAGAGTCACATAAGCTCTGAGATAGATATGAGGGCGTCATAGGTTCGCACCGGACATACCTCGCATGTCCCCCTGGCGTAGCCACAAGGTGACTAGAGCCCACCCTGTCCGCGACCTTATGGCCCACATCTCGCTACTCACACCATTGATGTAATAGGGGAGTTATCCTTCGTTCAAGTCCGTTACCAGGTTCATCAAACAAGCTTTACGGATTGAAGCATCCCGGTAAAGACAGTAGCATGACTCCAAGGGCATTTTATAGCCTTAAAGGGCGTCCATGCGGGCCGGCAAGCCACTAAACCTTCATCTCGGACTGTTGGTCCTCTTTGCAAATTCATGAATGCTTTATGCTGGGAGACTAAGAACTTTTGAGGTTTCTATAGTTCAGCGGTGCGACGAAGTGGTCAGGCGCTGTAAATGAATGGAATACTCCTAGCGGGTTACCCCAGGCTTGAGGTTTTCCTAATAAACCCACAGCGTGGATCTCACCCAAGGCGCTAAGCCATAAATCAAGTCCCTAAATGTCCTTTTTAGAGCAAATGATCAGATCTCTGCGCGAAATTTGATCAATGTAGGACCGCAAAACCGCGAAGTCCCGCTGCAATCAAAAGGCGTTATACCGCCACCATTCCCGTGTGCAAATATATAGGCGACACCGCTGCAAAGCTCGGCTCATGCGATCATAACCCCACGCATAGCTTCCTCAATGTTATTTGCACTTCCCCCATCACACTGATATGCCCGGATGAACACCATTCGGGGTTTAATAGCCAGAAGATCCGCCTGCCTAAGATAGATTGTGGTTTCACCGAAGTAATGCCAAGCCAGTAGGTGACAAGACTGTTATCCATTCACGGGTGTAATATTTGGCGGTTCTCCTACAGGGTCGTTCCATGTGCAATGGGCCCTCTTACGACCCCGAGCAGCCTGAAGTCTGTCGAATTAATCTTATTCCTCAGCCCGCGGTCAGGAGGGCCGTAGGTCATACAATCAAGTGAACTCTGGCAGCGTGACGGCAGAAATGCGTAAGAACAGGGCTGTAACGATCCATGCCGGGTCAAGAGAAGGCAAACGGGGCTCTAACGTCCGATCTCGACGAAAATCGGAGGAACCGTCGCTAAATCGCTGTGCGCATTATTTACTCGGCTCTCTCTTGCCCATAAGTTTCTAGGTACGTACGCACCAATAGACAGGGGTATGTACTTTCGGGTAAGCACTGATCGTGGTGTTGTCAATCGGCTTCACTAGTGCTAGTGCTGAGAGTTCACTGTCCTTCTTCCGTGCTAGTTAATGAACCGCTTTCTATCCGGAGCGGTCTTCTTTCGCTCACTTGTAACATGCGCTAGTGGCACTACCGACAAGCAAAGCTAAGGTGCCTCCTCATCGACCGGAGGTCCCTCCGAGTTTAGACGAGCTTTGTTCACTCAAAACGAACACGCTGCGCATAGAGCAGGAATCAGTAAAGGGAACAACCTAACTGCAAACACGTGGCGGCTTGTCGTGTCTGACTACCGGGCAGTTCGGGTCCTAGGCGGTTAGTGAGCGGAACGCGTCGCCGGGCGTATCCGTAAGGATTGAAATAATTCTCTAAACGCCCCGCGTCGAATCTATGTCCCTTAGGCTGTGCCCGTCATTTCCGAAGCGCCCACAGGTAAGAAAAGATGGGTTTTGCAAGGCAAGGTTGCCGATTGGCGTTCGCAGCTGTTTAACAGCACATGCCGCGTGCTATACGGCAAGGAGAGCCTCTACTCATGACCGTCATCACACGCCATATGCCGTGAACCCCCCCGAGGAGTAAAGCGATGTTCTGCTGTACTTACTTCACAATTGTTAGCCGTGGAATTCGCATTCATTCCAACCGTTTCAATGATTCGAGCAGGCGAGGCTCCTGGGTGTTTCGTAGCAGGGCCCAACCACGAACATCTCCTTAAGCATCCACCCACGTGTAGTATGCACACCATAGATGGCATATGATTGTTCGAATGCTACCGTGATGCGCCTGTCTGACCAAATACCCTGAAGTTGCGGGCGCTTGTCCAAAATATGTAGGCGGGACACAGGGCCAACGTATTCCCTACGTCCGTGTACCTAGCTCAGGGCAAGTTTCTTCAGATTCCATTGGGACCCTGTAATAAGCAGCTTTTAAATTACGCTCCCTTCAACGAGACGGAAGCGATTCCGAAGCACCGAACCCTCAGAAATGGACATAGCTGGTGTTGTGGTGAAGCCTGAAATCCGACTCGGTACTATTTGTCATGGGGCTCCGGATATTTGTTGATCTTCGCTGCATTTGCGTCAAACTACGACACAAGTAGGATGGGCGTACCGCGAATTCATGACATGCGCCCCGACTATCATGAGCCAGAATGTAGAATCCAGGCAGTACCATTGGGAATGATTCCGTTGATTTGCAGACGGCGCATTCACTCTAAAGACACATATTGCAAGATTAACCTTCACTTTAACTCATGTCTCATACGGGTTGTACCAGCTGCTAACAACTTGACGTGGATGGCCGGGAAAAGACAGTAGTGGGTAAGAGGCATCTATCAGCGATACCACTTTGAATATGAATTATCCTATTAGAACCGTTCGCGTCGGCTTCTTAAAGTTAAAGGTCAAGAAGCGCCGGCCATCGTTAGGGCACATAGTGGCTATGAGTTGCGAACGTCATAAAACTCGTATTTAGCGAGGTCTCGGGACAGGATAGGGTTGCTGCGTAATTGTACGCGGCAGACAGTACAAACGTGCGCGCGGCGACTCCTATCTCTCCCGCTTAAGCTTTATATCAGCCTGCGCCGGGTGTGCGCGCGAAGCGAGTCTGAGTCCCGGTCGCTAGTGATAAGAAGGCACGTGCTCCCGAATTGCCCCCCTCTAAGGTGTGGTCCTGACGAGACTTTGGATCACGCCTCTGCACAACCAGGGGTTAGCAAGAAAAGCCCAACCTCCTTGACGGCCGTTCGCCCAATTGTAATGTCCGATATTAGGCGAGCTCAAAGTTATCGGGTGCTAAAGCTTCCACTTATCTTTAGAGGGCGCACAGTTGAGGTACGGGCCCGAGAATCGGTTCTGCCACGTAGACTCTTATGTGGTGTCGTATGTGGCGTAGTTCAACCGCGTCACGACGAATCGTCATAAAGGGTAAACTATCCCTAAGGGTTTTGGAATCTTGCGCAATAGTCGCCTTTGAACGGAAGAAGCCTTACCCCTCTGCGTTCACAGGGTAGCACAAGCTGCGACGAGAGTTACTGGTTGTTTGAGGGGTGCCCTAGTAGGACCTCCGCCGTATTATGTACTATCATCCGAGTGGGCCACCGCGCCCGCCTTAAACACATGCTACCAGTCTGTGCGAGTTGCAGGTGGATCGGCAAGGGGGGGTCCGCTACGCATGTAACCATAGGGGAGGGGTAGCAAAGGTGCGAGGACCACATGCCGGCGTAAAAACGAACTCTCACATGTCAGGCTTTGCATTCTGCGCCCCATAATCATCTAGGCTTTGCCCCACCGTAGCGAAACAGTTAATGCTTTGTCGCTCGTGGCTTAACTTCCTACGCGTTCTAGTTGCTACCCGAAGCGGCGTGTGGAGTCTGCGTTTTTAAGACCGGTGTAGTTCGCATGCAGACGTGAGACCCGAGTTGTGCTTGTGCCTTGTGGTACAACTCCACATATAGTCGCAGTGCGCACGCAAGGCGCACTTCGTCGCTGGCCGGGTCGGGTCGTACGTGCGTTACGAAGCAAAGAGTTGTTTATTAGAACGCTGTGATCCGCACGTAAGACCCGTTACTAGCTGCTCCTCTGTTCTTGCAAGGAGTGGTCAGCACGTATACCAGAACAATATCCTGTTAGAACTGTTAGACATACGACACTTCTCCACCTGGGATACGTAGGAAGGTGCCCCCTCACAACTGATGTCTTCCGCATCGCAAGACAACGTTGCAAAATATTACCCAGCGCCGCGCGTAGTGTGCACGTGCTGGTCCCTCGCAGTACCGACGGTAGATTTAACTCCTAAGTCGTTAAAAAAATTGTGATTCTACGAGGAGAGGCCTACGGGTTCTTTCACCAATTCGATAACTTTCCGACCGTCATATTCCCAATGAATGGAATTGAACTGGACAACATATTACTGACATAGAATCATGCGAGTGATCAAGAGTTCAGGAGTAACAGGTGATAACCTCGGTCGTGGGCCCGCGATTAAACAGACCTTAATGCACTGGATCAACGTTATAACTTCTCTGTAATTGGACATATCTTGTATCCTACCCAGACACTGAGGCACGCGGCTGGCAAGCCCCCAGGACAAGTTCATGCTGCGATGGGCTTTATTCGGACTGCCGGGCCTGACCAAGGCCGATCTATGAGTAGGGCGCGGTAAGAGCGAGCCCCGTTGTCCCAGCCGTGCTGAGGGCCATCTGCCTGGTAAGATACACAAGAAATACGCCTAAATGTTCGAAGAAGGCCTTAGATGATGAAACGTTCTAAACATGCGCGCTAACAGGCCACACTGTATGACATTGCCAGTCTCAATGGGGGATACACTTGAATTAGCCAATGTCTTGCCTCGCCTGACACCACTCGACTTCGCTGCACGGAGCAGCGCTTTTCCTTCAGTAAGCCTATAAGGGGATCTCTCTAGTCACGAACTGCGGTTTAACCCGAGAAGACGTTCCTAGTGAGAGCGCGAGCTCCGAGTACGTTCGGCTAGACTCCGTGAATGGGAGACTTAGGAACTAAGCAGCGCGGGGTTTCGTTTATTGGTACTTGTGCTTGAGCGGACGGGAGCACTTCCTGAGGCACATGCCGGGCGGGGTCGCAGGTAGGCTTAGCAGAGACCAGTAGCTCGTCCGCCTTTCCTCCCGAGCGTGAAAGCGGTAGCCATACACGGGGCTAATAGGGAGCGCACCATGCCCACAGTAGGCCAGCCCGGGCCTCACTCCCCCCATTTTCAGGCTACCTGCAGAGCCATTCGGGTTCCGTGGCGTTTCAGAGAGACCTGACTATCGGTTTGTGTCAGCCGATAGTCTTGCGATGTAACACACGAAGGGATAAAAAAGCGGCCGCAGTGTAGTACCAGAGGTATTTAAACGTTAGACCGAAATTGAGTTTTCGAGCCTATCGAATAATTTCGCTAGGGCTAGGTGATCCATTGGTTGAATTTGCACGCTTGCAAATACAGGCAGTGTGTCATCCAGCTCGCCATAAATGTTCAGGCGACTGACAAGAATTCGAAACTCACACGCACTAGTATTAAGCTTGGGTCACCCTGAGGCACGGGCGATTGTTCCGGGATTGATATCGGACGCCGCTTTTTAAACGATGTACAATTATCATATTTAGCCCATAGGCTCGATCATTCAGCCTTATGCGAACCTCGAAGGCAGGCGGAGTTAGTCGCAGTCCTCAAGGTGCCTCGTAACAAATAATGGGCAGCGCCTGACAAGGGTTGATGTACACTCTCACAACACTCTTAATTCAAAGGAGCCCGCTTATGGATAAAACTAATCCCAGCATTATCTCTCTAGGCTTTTTTTGGGAAGCTTAATCTCACACCTTAATTCCTCGTTCGCGGCCCCGTTGACAAACCTCGACGCCCAGCCTTATAGGAACATTAGATACTCGAAATATGGCAGCGAGAAAGTCCGAAGTGGCTACAAAATGACAATTGTCTACATCGGGAGTATTGCCTCGGTCTTTGGTTGATTGGAACGGGGTTGCATAAAGTACGCGTACATATCGTTGCCGGATAGATAATCTCAGTATTATTCTATTTCATGTGTGTGTAACGGCTACTCCGAAGTCCTGTCAATCAAGACGGGGGCAAGCACAACAGTTCACTCACGGATAGCAGATTATTTACGGCTGAGTTCAATATCGGCAGGAGGAATTAATTTGAACGAAAATACACGCCCCCGGGCTACTGTTTAGCAAGACTATCATACGCAAATACTATGCCATTGCTCGGTGGAATTTCGTTTCCGGACCATGATAAACCGTGTTGTTATTCCAAAAGCGAAAATTTTGATTTAGATCGGACCCTAGCATCCAATGCAGGATCTAAAATAATAATGCGGATAAAATGATAAATTCCCTGCGATCGACGGACGCTAAGTATTGAAGAGCATATAAGAATTGAACGGGTGGCTCCTTCGGTTATGTGGCACTGTTTGCTTGCCTGGCAGAGTATATCAACAGTGATCAACGCGGGAAACTCGGCCGCGGTCCGATGCTGTCTGCTTGGTTACCTCCGGTTTACCATCTGGTTCTACGTCCACTTCGTGCATTTTTGTTGGGTAGGCGCACCTGATGAATTGAGCTGCCCCCGATTTCGCACGTCTGACATCCGAATTTTTTGTCTCAACTTGTCAATTCCGGATCGTCCTAGCTCAGAACCCACGGATCAGCTCGGATAATTTGTTTGGTTGTTTTTACACGTTTATCATACGAGCACAATGGATGGGGCTCATACCCCGGCCCTGCCGGCGTGTGACGAGTGGAGATATTCCTTCTCTAGCTGTTCCTTGTGTAGGAGCACGCTTGGTCCTAACCGTAGCCACTTCGCGATATTGAATGGTTATGTTGCAGCTACAACCAGAACTGGTTGAGGGAGCCCCGAGCCTCGATCGTCTTCACGTCCATACGCATTCGCCACCCTAGCTGGGCTTAGACGTTAAACTGCGACCGGGTAATTACCTAATTCAGTCAAGCGTCCCGTTCCACATTAATATTCCAGATTTGCTTAATGGCCCAGTTAAATCTATCATTACGTAATAGCTGTTACTCCCTAAAGCGCCAAACTTTTGACCCCTTGTTACTTACAAATAAACGGGTTGCGTCTTTCTTTCCACGGACCTCCATGCTCGAATATTGTCTCTTTCCGTATTGTACTGTACAACTCGGTGACAGTTCGTAACTACCTTCAATAGCAACCAACCCCTGTTACACCCGTCGGGCTACTAGTTTCTCTTTACAGCCAGCGTCTGCAGGTAGCTCAGCCCTCAGATTCAGACACAATATGAGGCTCAACTTTGCACTGAGTCCGTGGCCGGAGGGCTCTGGCTAACGGTTACGTTAGCATGAAGTACTGGCTTCATAGAGCCGGGCCTAGTCACACTGGTTGGACACTACCCGGATAGAACGCAAGTTATAAGATATAGGGCAGGTTCTGGGGTGTGCCTGGATATTTTTTGTCCCAGGTTCCTTGCGGCATTGCGTTCAAGGTCTCTCTTACCCAGTCGTCATATACAAGATAATACTATCGACAATCTTGACAACGTCTGTTGAGAGCTCGCGTCATAGGGACGGCAGCGCTAGGGAGGTATGCCCAACCGGGAATGTGGGGTTCTCCACACCGTATGTCCGATGGGCACAACTAGACCGTGTCATTATAAGAAGCTACAACCGAGATGCCGCACCTCTTTAATGTTGATCCTGTATTGTGAACTATCACTCAGCTAATTCGGGGCCATAGGATATAGGCTTCTAAGTCGACTTTTCCGATGAAAGATCACTATCCAGCGTGTCAAGGGTAAATGACATCAGGACGCTGACAATTTGGCTGAATCCTTGGCGACGCGGCAAGAATAAAGGCATAGCACGGGCGTTTGAGGGGACGCTGATTGGCTCGGGTCCAGGTCTGACCTCCACGGAGTCCGGATTCGAACTCGGTCAGTCACACGGGAGGCTTAGGAGCCTTCGAACGGACGATAATATCCCGTTACTCGCCACTGTGCCTGCCTATAATGGAAAAGACAACTTTTTGGAAGGAGCTCGCATTGTCCGCGGCCGAGCGATTTCATGTGGCTTTGTGAAAGAACTCGAGTTGGACATAATGTCTGTATATGTATCGCCGACGCGACATATCCTGTACGTGTTGTCGATGATATGAAATTGACCTACTTACATGATACCAAAAGGAGGCGGCCCCCGGAAGGTTGGCCCGAAACACGAGCTCCTCGCAAATGATGTCATGACGATGGCAGAAGCCGAGCTCACGTCTCATTCGGTCGCAAATCCTTGATTCGTGCCGTAAGGAACTTGGGAGGGTAATAGCAGGTGCCACGTTCTCCTATTGTCGGACGCAGTGCTTATGTAACTGATTCCCTGAAACGTAAGCTATTTCGTCCGGAGATAGAACATTATGTCCACAAGGCAAGATATGTTTCCTATGAGAAGAAAACGACGCTTAATGACTTGGTGTTCTTTCTCCAGGCAAGATACGCGAGCGCCTACGGAACAAATGACGTCGTCTACGACGTCCAGATCCCAGCTTTTCGTTCGCTGCGGCCCCCAACTTTGCCAGTAGTGCCGATTGTGCGTTGCGGCAGGGGTCCTTCATACTAGTGCTTCATGCATTTGCCAGGTACCATGGATCTGCACTACTATCAACCGGGGACCGCGCCATCGCTTATGGGGTAGATGATCGCGCCACATCGTTAAGCGCGGATTATCGGAAGCAATCGTCCCACGTATCCTAGGTATAAGATATAAGTTGCAACCGCCACTAATCCCTCACACTTTCCACGGTGGAATCAGATGTCAAGCACTACAAACTTGGTCCACAGATGGGCAAATATATGTGCTCATCTCATAAAAGGTGTGACCGCTCGTTCCGGAACCTCAACTTTTGCTCGTAGCGGGTATTCCTGACGCGATTCACCAATCGGGGCCAACGGCTGACTTAGACCCGGCAAATAACACAGTCCAGCGTAGCTTGCGCATTTACGGCTTTTTGAGCTGGCGTTCCCGCCAGATTTGCACAATAACATCGATGAACCTGTGCTGCGGCTAAATGATAACGGAATGGACAGTTCGCAGTGCTTCTGATTGAGTTCGTGACCAAAGTCATCCGTAGGCAGGGCACTCTATACCTCACGTATGTAGCCTGTGTATCCTTGCCCAAAGGCGCGCGCAGCTCGAGGAGGCGGGATTGACCGGGACACATGTATTCGCCTCCGAGCGAACGCAGTAAATATTCATACGCAACGAAAGAGCTTCTTACGGTATTAACAATTTCATCCGGGGGTTATCGAGGATCCGCGCCACGGGTCTGCGCGAGACTCACGTGGCGGCGGATGAACCCGGCAACAGTCGGTGCCCCTGCTCAGCAGAGCGTTATTGCGAAGTCCATGAAAACCTTATTCACTAACCCGGAACAGCCCCTTTAATACCAAGTGTGAGTAGAATATTCACGCATGGGCAGGGTGTGGCGAAGAGGCGGCCACACATCGACCGGAAATCTCTGTCCTGCGTTCCATACCCCGACGAATTTCATTTCCCCACGGACTAACTTTCAGGGGGAATAAGCGAGGTACCCCTGGCAGAAAAGGCGCAATGTCTGATGAAATTTCTCGTGATGCTCGTGTGGACGATGGCAAAGCTCATGGAATTAGCTAGCAGCAGTGAAGTAAAAGCCGCTTCGGCGGCGACGGAGTGTATCACATCGGGTCGGATGTGGTCGCGGAGTGACGAGATCGAGGATGTGAGAGATAAGGCCCGTAGATCGGCAGGTGTGTGCCCTACGGCTCACTCGTGGTCAGCCAACTGAACTCGTGACCCTCGTTATGGATCTTAAGCTCTAGTAGGACAGCCCAACTACCACGTCTTAGAAGCCAACGATAAGCCCATAGGGCAATGTTTTTAAAGGAGCCCCCGTTCGTTTCGGCCACAATTAAGAATTGAGTTGATCATGAGGACTATGTGATTTAAAAAGTACACGAAAGGCGCTCAACGGAGTGTACTAGGCATTAATCATCCGAGTACATGCTATAGCTTGTCCAACACTGTGCGATGCGGCGAGCGCGGGTCTGAAACGCACCCGATATTGGTTATGTGTTGGGGTGCCCATCGCGCTGTGTCCCCGGTGGGAAAGTGATGTGCCATCATACAAACGATCGTAAATCTGCTGATAAGGACAGACGGAAGGCTAAAATGGAAAGATTGAGAATTGGGCGACTTTCTTTATTCTCAGAAGCAGGAATAGTCATCCGTAGTGCCGTCAGTTAGTAACAAATAGTTGCACGCTGCGGGGAAATCCCCCCACTCCCGGAGTACCCAGCAAGTTAGGAGGGTGAATCCCGGTTGGGCTCAGCGGACACATGGTGCCGACCAGTATTTCCGCATTTTACGGGACCCATACAACGCGTAACGCTTGACACTGGAAACAATAATAGATGTGTCATGAACTTCTAAAGGTCAGTTCTGTCGTCGATCAGTGCTCTCCGCGATACCCGAATGCGATTCTAAGAGTGCAGCTTTCCCTAATTTGCTACGCGACGTATAAATTGGCCTAGATTGATGGGTGGCGTAATGAAAAGTTATGCTGTTGGTTCGTATCCTGTGTATTTCGGTTCTTCAATTCGCACAGTGATTAACGGCCCATGACTGATGGACGTGGGCGTGTAGTATGGGTATACCCCCCTCAATCACCCCGAGTGCACCTTCGTGCGAGAAGCACATCGCCTACATGATTGGGTACCCCCTAGCTAATGACACCTCCGGCCGGTGCGGCGGAGTCGTAGAATGGGCCAATGATTCATCCCCTTGTTTCGTCAGTTCAGGTCCTGTGATGCACCGTACCTGCCTTATCATTCTCGAAGCCTGTTTAAGTTTCGTTTGCGAATTCTGCGGCCTGCTCTGATCCGGGGAGACCTTCGAACATGTGGTACCGAGACTGAGGTGAGTAGTTCAACCATTTAACTGGAACAGCTAAATGTCGCTTTCGCCCCTTACTTCTTGTATCTTTCGTGGCGTTACCATGAGGAGGGCATTTCTGACTGTCGCTTGGATGGAGGAGTAGAATAACCAGTACCCTATTCTGGCCCTGTCAGCGGCACCGGAAACCGGGCCGCACGTGTGTTCGCAGTCATTTGTTGACGAAGCATGCGTCCAGTGAAACGTATCAGGCATAACTTGCAGGGTAGGAAAATAGGCACTCGTAGCCTAGGTGCAAGGCGTTTTATGGCGCTAGAACTTAGAAACGAAAGATCCGGAGCTGTCCGATAACTAGTTTAAAGAATCACCATCGGGGGATTGCCAAACGATACTACCATTCCTTACACCAGTGAGGGGGCGCTTAGTGGGCATGGAGTTGACGCGGGATGCGCGGGCCAACAGATTCCAAAAAGTGACGCTATTTAAAGAGGTGGGCTATGGAATCGGCATGCTTACAGCTGCTCTTCCTCCTGTAGTAAGTATATGCGACCGATGGAGGTCAAAAGGTCTTGATTCGTCGGTGGCCGATGTTATGCGGTGAGATACCTCCCAACGGCGTTGATAAAGGAGGAGGCTTACCATTACGCCCATGTTCGAGCCCCCAGCCAGACATCGGTACCAAGAAGGGTAGTTGGATACACCCCGTTGCCACCAACGAGTGTCTTGTGATTGGCCGATTTCACCAAGGGCAGATCGACCTGGCGTGGAATTCCCTTATGCAACAGAGTCGACAGTTTGGGGTGTAACAATTGTGCGTAGGCCCAGCCGTCGAGTGGTCCAGGGCTGGTACTATACAGCTAGCCGTACAGAATACTCGAACATTGATCACCATGTGACACATCCGAATAAAGGCTAGCTACTTCCGCACAAGCAGATATATTGCCCCGAGTGGATTCCCTGGGGTCTCTGAGGTATGGGGATAACATACTTTTTAGGACTACAGATAAAAGTCTTACATGGAAACCAGCTACGCGTGGTAAACGGATAACGCCACCGGATGTTAATTGGCCTCGCGAGAAGTTTCATATGCACTTAGGGGTCTTAAGCCGTAGCGCTCGGTTTATGCGGCATTGCGAAGTCTGACGAGGCCATTCGACAAGTCCAACAACTTATCACACTTGGTTTGTGCTGGGCTGTGAAGTCTGCAATTGCAGGTAACTTAGCACTCCGTGATCTACACCCAACCGGCCGTACCTCTTGGGTAAAGAGACTGACCCGGGTGTGATATCTGTGGTAGCCAGGTGTTCATTCAAATAAAAATTGTCCTAGCATTCCGACTCTAATTTTCAAACCGTTGCAAAATTCATCGTTCTAAAAGCAATAGCTTGAGAGGTCCTTTTTTACGGGTCACTGCATCAATATTCTTTCCTCTACCACTCAGTTGATCTTAGTCACGGGTATAAAATATCCCTACTGTACTGTTTGCCGGGCGCGACGGTATATTACCCGTGGGGCGGCGCCATCCGATAGACTCGTATATATCAATCACTTCCGCGGAAATTTTCAGCGTGAGCCAATCGATTGACACAGAGTCCGGCACCGGGGTGACGCATTGAGGTCCATGACACTCGAAACTTGGGCTACGACAGGCGCGGGACGGCCGGCTCGTTACTGAACTGTCAATGGGGATCGCGTGCTTACGGTGCGCGAAGGATTTATTTGAACGAAGGCATCTTCTTAATTGTCTTCATTAAAATGGCCTGGTATATAGTTCGCTAGGCGTTTCTACAGTACGGGTAACTTTCTCTCAAGCAGGAACCGCAAACGTCGATGCTGCAGTGGCATTACGGGGTGATCTTAACATCAAGGAATATCTCCGGTGATTCGACACGTCTCCCCACTTAGCGCGTGACCTCTGACAGGTACCGACTGTAAAAGATCTACGTGTTATATTCAACATTATCCAGCAAGTCGTGGAGTGCGTACATGTTATTGTTTGTGTACTAGAACACTACTATGACGGGTGGAGCCATCATGGTTGACACGGAAGGATAAGGATTGCGCACCCATCAGGAACATGTACTAGACACTGCGCGTTACCACCATAAGCCAGTGCCAAGGATATTGGAACGCTAGGCTTACAGTAAGGCCACAAAGATGAGACTCCTAGATCGTCTGCCGTAATATAACAACTGTACTGCTACAACGACCGATATGCGCATGGCATGGATGCGTAGTTTTCAGGGCATTCGGTATACCGGAGCTGTGCCGAAATCACCGTTTCGGCCACGACGCTCACACGATGGTCTGTGAGACAGGGGGGCTCGCAATCTTCCCCATGAACATGGCGTGATTCAAGAGGAAGCGGTGGCGTGTTCGTAGGCGGGGCGCTTTTCATTTCACGAGAGTAAGACAATAGCAAAGTGACGGCCACGATAAGGGAACTAGAGAAACGAAATTATATTACACGTGCAGTCCGGATGGCCTTGCTGATGTAGCTACATGTCCCACTATTCGCGTTGCTACAGGGGGTCTAGGCGTCTGTCGGAGATTCTATTCAGAACATATGTACAACAATCGGCTAGGACCCACTGGCTAAACGCCTGTGGCAGAGTCTCGCTTTCTGTCAAGTCTACACTAGTAATAATGGTCGCGACTGTGTGCTTAAGCGATCCCGGGCGTATCCGATATGAGAGGTAAAGGTATATTGCTCGTCCCGCCCCCATCTAGGTGCGCGTTTTTCTAGATGATTCAGACCCTCTAAGCACCGACGATACTAGTACAAGAACTCTCCATGGTACCCTCATGCAGCTGTGACGTACCGTGTAAGTATCACTGTATAACTACGATTGGGTAATGCTCGTGTACCTGGTCTATAGTTTACGTATGGCACGTGCCAACCGCGCACCTTTTAGGATTCGAAAAGGCTGCGATCGCGGATGTGCTGGCTCGCTTCACAAAGAATAGGGCGCCGTATTAGCTCGCGGCCGGGTTGCGTTCCCGCTAAGTTACTCTATGCACGCTGGTATAAACTCTAGAGATATAAAATCATGAGCCCAGGGCGGGTTGTAAATATCAGCAACGTAACAATTGTGTGCGTTCCTTGGTATCTGCGCAATCGCGATTCTGGGTTACCGCGAGAGCCCCAGGTTCCGGTTTTACAAGTACAGGGCACAAGAGAGATACAGATGAGTGCACGCAAGATGCATTATCGCCATAACTGAAATGGAAGTTCCTTCCGCTAAAGTTGTACCGCACCGAGAGAAACCATTACTCCAAGGACGCTACAACGGGCTCATCTTCCCGTCAGCGGGTATGCAGTATACTTTACGCGGCCGTCCAACATCCCAGTCTATACCTAACCTTAGACATCGTCTTACAACAGCCGGTATCCCTGTGACCGCCCTACGTACGTTGTGGGTGGAAATCAAAAGACTAAATCAATGGATTTCGATGTCGGAGTGACTTTACTCCATGTGAATAAGACCGGACGAACGCCAACTCGAATTGTACCCGGCTCTCCTTTATCGACAGATGCGTCAATACACAGCGAGATCTATGCCTCGAGCAAATCCGGACACTTGACGTCTGCGATCGTAGAAGGACGGTTTTGTTAATCGTACAAACTACCTCCAATATAGCCCCTCGTACTGTTGACAGCGATACGGTGCTATGGCACTAATCTTCACTGGCGTTTATGGGTATGACAGCTTGGATCATTTACCCCTGACCACTCTTACATACGGAAGACAAATTCCAACCAAGCGCTGGATCTTCGCCAGTGACACCAGAATAGTAACCGGGACCACACATTCCTCAGCTGAAGGAAAAGGTAGCAAGTCACTGGAAGGCCTGGGCACAGGAACGATTGCCAAAATTCTTAAACGAGGCACGAGTAGTGATCCTAAGGCACGGAAACAGCGCGTGGCCGATCTGTCGTGCACCTTGTGGTACTTTTCTGGACGAAGAGCAACGTGTATTAACTCTTAACGCTCTTCTGACATGGCTCACAACGCAACAACGTACCGTTTAAGACTCACGGACACCTAACGCTTCCAACCCCCAAGTATTCACGATGCTCCCTCCGTCGTATACCACTCGTTAACTTGATAGGCTTGCTGAAAACAGTGCTCAGGCCCGGTCGGTCGCCTGTGGTAGCTACCTTACTTTACAGCGAATCTAGCGATAAGTTACGTTCAAACAAGACTGACTTTAACGCCGACGGAGAGTTAACCAATGGACCTTCCAGCGGCGCTGACTGTTAGGTGTGCAACTCCCCATGCCAATTAAAACCAATGGGCCTTACAAAATATGATCTGAATGTCCACATTAGTCTGGGAAGAGTCATATTGTGTCCATAGACCAACTTATCAATAGCCCCAGATACTCCCTTGCGGTATGGAGCTAGCATAGTTGCTTTAGTTATTTGAGAACGTGAACTTCCTATTTGTTGTTTACAATTCTAATCGTCTCCTATGCGAACACATAGAGTCCTGACCTAATTCGTTACGTGGCTTGGAAGGTTGCACAGGTCTATAAAGCCGTAGACAGTGGTCCAGATCGTCTTTGCGTTAATTCGGGACAAATCCCTTCCAGTTAACGTTACCACACGGGAGCTCCTACACGAAAATGCTCTTGGGTGTCCTATAACCTGTACATCTACCCAGGCTCGTCGCACCCCCAGGGAAAGGCCACATCTGCGAGGGCTCTGGCGGACCGTGAGTCTTTATTCTTACTCCAACTCCCCCGAAGTAGGCACTGAAGGCCGTTCGTGTGACAGTTCGACCCAGCAGCTCCGCCGTAAAATGCTACAGAATGAGTGACCCCCCCAGTACGGACACAATAGATTGTCCCTCGTCCACCGATATGCGACGCAATTATGCTCGAGCACAGTTTGCATACGATGCCTACAGATGGGTACCACTTGGGCCGGGGCGACTTTCGCCGGGATTGCCGAATATACGTAATGCCGTCATCGGGCCATTTAAAACGGGGAGACTGGGTGGGGAACAGTGAACCCTGAGGCTAGGCGCAAACATTGAGGGGATCGGACCGTTCAAGCCACGAATCCCACGGCGAAGATATCTAGGAACATGTAATCTGACGGATCTCTTACGAAAATCAGAGAACTGGTGCATCAGTGTCATGCCTTTTTAGACATCATATACATGTCTTAGCACATGGCAATTGGGTGCACAACATCCTTGAGTCGAATTCCCTACCGGTTAAGGGGACGTACAGAACACAACATAGGAAGTCTAGTTCGATGACGATCGAAAGCTCGTGCAACATTTACATTTCACGACGGACTCATTAACGTTGCCCCGGCGTGATATACGTCTGCCACTCGGCCCGTCGTACTAAGGTAATCCACTTGAAAGAGCAAGGTCTCTTGCAGGTGACAACACGTGCCTTTTCCGGTACTCAGGTGAATATATCTCGTCCAATGGGCCTCGCCGCAACTATCACCCTCGTTATCGACGCTAGGACGGTTGGGGATTTCTGCATTGGCTCGTAACTACCATATAAACTTTGCAAACCGGATTCCTTGCGTAGGGACCTTCATTGATATGGAAAGCTGCTCATCGTAGGGTATTTGCGCCGCGCAGTTTAAATGTCTTAATGCTGCGCCTCTAACGCTGTCATAAAACGTTTTTGTGAATAATAGAGACTAACTTCCGCTATTTCAAGTGAGTCTTGCTGGTCAGAAACAG G . PASS SVTYPE=DEL GT 0/1 0/1 +20 700010 . T C . PASS . GT 0/1 0/1 +20 800000 . A . PASS SVTYPE=INS;END=800000;SVLEN=6027;CIPOS=-16,22;RIGHT_SVINSSEQ=CCCCGTTTATGAACTCAGCGCCGAACAGAAAAAATAGCCCCACTTTAAGTCCGCTTTAGCGACTCTAGGGTCCGAACGCGCTGTTTCGTACATGGCACGTCGGTAGGCAAGAACTCCCGTCCTCAGATGAAGATGCGTAATATCCTTACGTATTTTGGAACTCAGGCTGCCGAGCATCTTATTGGGAGACTCTTACCACTTTGCCCGTAAGCAGGGAAACGACATTTGATAAAGGATGGCAGGGAAGCTTTTATGCCCCTTTTCCTACTACAACGTCGAATGTTGACTTCCTGGTTAGCGTTGTGGCCTTGTACTGACCCTACTAGGGTTTCAGCTGCCTAGAGGACATTCGACCGACCCACGACCGCAGCTCGCGGTTCATACACGAGAAGCTACAATCCGCTTAAGTATTTGTTCTTTTCGTTCTAGGGCCCGCGGCACCAAGGAGGCTTCAGAAAGAGAATAATTACTCGATCGTCCCGTAAGTAGTGTATCGCTAACAGGGCCTGCGTCGTCCATACTAAGGCAAGGTGCTCCAGCAGGGCATAGGAATTGACCGGCGGGTAACATTGGAGACAACATGTGATTTGTTGCTTAATCTCGGTTAACCCGCCCCGCTGTAAAGGCGAGACGGCAATCATGAATTCTAGCACGCACCCCGCCCGTCTCTGTCTTCAAAATGTATTTTTGGCAACGAAGGATCAGCCTGTCCCGAATCGACACTGTGTTCCTATGGCGTAAAGAATTCTGTTCCTGAATCGCGGGCGCACCGTAATTCTTACTTTCACATCGAATTGTTAGATGCTGACGAGCAGAGCGCAGTGCGGCCGGGCGGAGATTGCAGGGCTGGCAGAGCCATTGGCCGTTGATGGTGTTTAGACGCTAAGCTAACCCTATGCCTCATGGATACTTGCTACACAACAGTGTCTGCGTAGGCTGAAATGGGGACGGCATGAGACCTCAGTGTCAACACAATTTGATGCACTGGGTTTTCTGCAACTACTTTACTACGGCTTTGTCCTTAACGCGTTAAGGGACTCCATCTCATCCGTATCATAAACTCCGTAGTGTATTGGGGCCAAATCTAGAATACGTACCGTCGACAATGCTCACGAGGGTTACTCAAAACTCGGCGGGGTGCCTCAATCCGCGTGCCGTGAAATGCCCGTATTCACGACGACTAAGCACTTAAGTCTCGGGAGCTCTGTTGCGTCTCGTCTAAGGGCAGTCTTGCTTCCTGTGTCTGCAAGTTCCTCTCTAGTGTTTAGGGTGCCTAATATACTCCACGTGTGTCTATGGACTCCATATGGTAAGTAATGGTGTTTGATAAACCCCTGGCCCTTTAGGTTCTACCTAGCCTAACTTCTTCCTTTGACTTTTACCCCCATTGATCCATGTTCGTCGAAGTGGCCGATTGAGGCTGCCGCATGGCCAAACCGCTAACCCGATCGAGAAGGTTGCAAGGGCGCATCCGCAAATAAACCATGGTTGCTAATTGGGGTGCAGGCGTAGAATTTGTCGGTTCAAAAGGCCCTCGACCTGCACAATGACTTGCGCTCGTAACTTATGATAGGGCCGGCATGGGATTATTCGAGGGACTCCTCACACTCAGAAGTTTACTCCCGGAGCACGACTTTACGAGGTGTGTTGCTTTATGATGGCATATAAAAAAGATGCACCAATCACCAAAACCCAACTATCCTTGACACGATCAGTGCGCGACCTACGACTACTCTAGTGGTACGACTATCGCGATGGAGGGGATATTCGTATATTTGAAGTTCATGTATTGATTCGGTTATGGCGTCTCCCTTAGTGTTTATGGACTTCATGCGTGCCCCTTATCCGCCCGCAGGCACCAATCACATTGTGGAGTTAGTTGGAGCGAAATTGGGTGGCTGTACGGTCAAACTAGAAGCATACCTTCACAAGGGCGTGGCGCTATGGGAAGTGGACCTGAGGGACACGATGGGTGAGATTCGGACACTCTGTCTACAAAATTAGGAGGTACCTACTGCTAGCGAGCTTCAAAATTCGGGAAGAGATCCTCGTACCACGTATTAATGAAGAGCCAGTGGAGCGAAGAAATTATCGCAAGACCGACCCTGTGCCGGCAGATGGACGTGTTAAACATGGTACATTGAGCAGTCCGACTCGTTGTATAGTTACCACGTGTGAGAAGACTTAGCTCGCAGCTAGTGGACAAGAACTCGGCCGAAGTTTCGTTCCTGTATTGCGCGTGTCCAGGATGTGAACAGTCCAACTTCATTATTTTATTCTGACTTGACACTGGACGTAAGTCAGCTGCTCAGAAACCGGAGTTCCCTGCCTTGGCCTGGGGGCCCCATTTGCGGATGAGCCCACAGGTCTCGTAGACTTAGGTGACGCCGGGATCTGCTGGCCTTATGTCCCTAGAAGCTTGGATGACCGGCCCACGGCAATGCGTAGTCAGGGAGGTATCCATGACGTGCGTGAGTCGGGCGAAGAGGGCCCCACATGCACCTAGAATAGCTATGTGTGTTTCTCGGGCGGAGCCCGACGTCGTCCCGCTCATATCCAAGTGCTTTTTCCGGGGGTTAAGCGGTGGCTTGGGCACAAACGGTCGCCTCCGCCCGCTTGGTCTCTCAGGTATTTCCGGGGGCACTCATAAACTACGAACGCGATCTCCGATAGCCTTCAGTTGTGGGGATGCGGCTAAATCCAAGCAATTGCGACGCTTTGGGTGTGGTGGGGGTTACTGATCCGGACTGCAAATTACTAACTCCGTCACCTATCAACACGTCTCCCTAATCTGTTGGAACCTCGCTCTATGACATCAGAATGCGAGCGCGGACATGGGACATGTCGGGACAATCTATTCTGCCTCTCCGGTACTGGGTACGATAAGCGCGACACAAGATTGTGCTCTTACTTCGCCGTGTTACCGGGTAAATCGCCGGGATGCTACTCTTATATGTGCCTTCTCACCTGAAGCCTTGCGACCTCGAATGATTTGGGTGTGAGTAAGCACCCGGGATCGAAGCTGGTAAGCACGTCACCATGTTAGAGATACTTGACCGACGATGCCCTTCTACGGCTCGGTTCACGGTGCCCAGCGGGATCCTCTTATCCCAGCCGGTGCCTAGCCGATAAAAGCTCACAAGCTTAAGGCTCTGTCAGGGGAGATGTGGGAGAGGCTCGATGAGAAGTCCTAACGACACCAGAACCCCAATTAGCACACATGGCTCTTCCGGGGACTTGGCTCTCGTAACTGCCTGCAATGTACTACGTCGCATGCTCATGTACCAGACATTATGTCCGTCCTTAACAGTCGTATTGGAGCAAGTTGTGAGTACAAACAGTACACAAGCTGTAGGTCACTCCCCCCACGTCTACCCTATATACTATAAGTCCTTGTAGCCAGGATGAGTAGGCCCCGTGTACCTTATTTGAATGCGCACCCGTGACTTCTGGTGGAGAACTTGGTCACGTCGGGTGGACCGTGTACGATACCCCACAGTGCCCCAGGAGGTATGGAACGATGCTGCCCTGAAAGGTGGAAGGCCGGAGTTTTTGTAGTTACAAACAGTACTCAGCGCTATCAGCAAGTGGACACGGAGAAGTAATTGAATGACCGCCTAGCAGTGCTCCGCCTCCGGGCGGCAGCCCGCGTGCCTCAGTCAGAGATCTCGAGCACGCACCCTTGCTGCTTCCGACTAATGGGAAGAAGTGGAGATGGCGACCCCCACGCGTTATAGTCCCAAGGTTGCTTCCAGGAGCTATACCCGAACCTTTAGGTCTAGACTTGTCGAGTTTGCGACCGTACTCGCTTTGTATGTCGACTTTTTTGAAAAGACAACCGTGGCCCGGTCACTGTGTCTCCAGTTTGGCGAGCCGTAGTCAGTGATCGCGCTGCTCGGGATCAATTATCTCCAACGGTCAGCAGATCTACGGAGTCGGTGGCCGGTATAATGCTGGAGGCCGGTGTATGCAGGAACCTAATAGTCCCCGAGTGTCGATCTGTACGGGAGTCACTAAGATAAGGCAGAACTGACTATCTCTCCACCGCTACGTAGTCCAGTGCCAAGGTGTGGTCATGGCCCACATAAATCAAGGATTTGTATGCTAGAATTACGCGATCGAGTGACACTCAGAGTGCACTGGCTAAGGACTCTAGCTTTGTAAAGACAGCATTACATCAACACTCGTTGCATTCCTAGACTGCGGTTCCTTCGGGATCTCCCCTTGGTACTTCCTATATTTCCTGAGATGTGGGCGCAAACAAATGCCAGATCCCGCCTGTAGGCATTCGGGACGGGTACTACGCGATGACCATATCGAGATTGAATCTTACGTATCTCCCTACAAGTGTGGCTTAAGGGGTTAGCACCGACAACTCATATAAAAACCAAGTAAAGAGAGTAAACACAGTGCGGAGTAGCCGTACTTGCGAAGCGCCATTTGGGCGCGACCTTCCGAATTTGCATCCGACGTCGGTCGTATAGCAAAGAGCGATTCTGAGCCTCCAGTCGCGGCCACGTCGCCGCTTGGCCAATGTATACCAGTTGTGAATAGGTCGCGGAACGCTAATGGAAGTAACCCCTCCTATTACCAACACGCCTCAATCGTACCACCGGTACCCACGGCATATAGAGACTATACGGCGTCGCGGCGGGCCTCCTCATGCTCGTATGGACTACACACCATGTCCTAATAACCTTGGTAACATTACGCCTTTGAGGGGTTCTTTATCTCCGATTTCGCGGTAGATAAGGCCACATGACATTTTCCGTTCGAGCGGACACGTGTCGCCTCAGTAGCCTATTGCCGTCGCCCAACCTACGCCACTGGCTCATGCCATGCCATCTCATACAATTAACTCCCGACGTTCGTACCAGGTGTACCAGGGGGTCCATACTAAGAGAGTGTGACCTCCAGATTCTAAAATACTATGTGAGGAAGTCATGATTTCCTCTAGTCATTGTGGCACCGCTCGTACCGTGAATCATATCAGATAAGAACGATCAGTTTGCGACTGTTATTCCGAGGGTACAGTCTTTAAGACACCATTCGGAAACGAAAAGGGACTAATGGATGCCGCGAAAAACCTAAAAAGGAAACAAGCTATCGATCTGTGGCGCCAAGGAGGGCGGGGCCCCGCATGACTCGTCAACTCCCATAGGCACCGCTCCGGGCCGGTAGCGACCGGAAGGCAATTGCTACCCTATCATATAAATGATCCTGGTCATTAGTTGTGCCCCGTATACTTGAGTCAAGTATTCCGTCGCAGAGACTACTGCTCATCCGAGACAACTTCTTCTCTAAGCGACCCGGGCGGACAAATTCACACGCAGATGGGAATTACACTAGGGGTATACTCACCCGGGCCTAAGGAAGGCACATGAGTGGGGCGGGCTGATTAGCAATTGTATCAAACTAGGGTCAGGCACACATAATGAAGGAGCAAATACATTGCACGGATATAGCCTAGTCGAGTTCGACGCGGAAGAGGTAGGCGAAATAAACTGTGAAAATGGGCAACACCTCACGAATGGTCATGAGTCAATGTAAAATCTTCGCGGCTTACTCGGCCTATTGCTATCGTGACTCCCAGGCCCTCAGTCCACCTCTCGTCAGATACTAGTTCGGGAGGCTCGAGATAATTGACCCTCCCTAATTCAAACTCAAACGAACTCACGTACGGGTAGGGCACCTAATTCGAGATGAAACATGCCTAAACGCCTCGAGAATATGTCTGTTTTGTACATAGTCTGTCGCTTATTCCACCACTTCAATCTGAAAATAGCGGACTAGTCCCGAGGGCCCCGATTTGACAGGTGGTTGAGAAGATCAAGTTGCACGCTAGCACCAGACCCTAACTCGCAACTGCTCTGCCTGATAAAAAACACATGAATCTGCGAACCATAACCTTCTTTGCCATTCTTTGTCTGCGGTTAGCGATGGGGGGTGTAAAACCACCTGCAGCGCGTCCCGATGATAAGCTATATGGGTTCACGTGCAATCCCAGAATCCTTTGGGGGGTGGATCAAATTGAAGCGAACGCAGCGTTGTATCGACGGTGAGCCCGCACATTTGAACTCGTTCCTCGGGTTCTTCGATGAATGTGGACTACGCTAGTTGACAATGCCTGCAAGTCTCCTCTCTCCCCCACGTGTAATATTGTACATAGTCAAGAAAGCTACATGCACGCCGACGTATCTTCTGTGCTTATGGATCGTTATAAAATTTTGTACTTACAGTGAAAATATGAAGGATGAAGCCTTAGAACTCGCTGCGTGAGAGAGAAACCCACCTATAACAAGACGCACGTGGCGCACATCCGTCCCCAGTGTTCAGCGACAGTTTGTCTAGCCAGTGAATCGGATCAGGCGGTCCTAGAGGTCTAGGCGACTTATGATCTTAGTCAGTAACCCCAGTAATTACCGTGATTACCATTTACAACGGTTAATTGGGTTGGTCTATGGTAACGCACAAATTACTCGTCATACCTGCTTAACATGCCTTCGGGAGTTAACGCTGTCGGGCGGGGTCAGCTTACATTACAGTAATCCGGCAAAAGACAAACCAATGCATCTCAAGAACCAACATAATAAAAAGCCTTATCAAATCTGGATCACAACTAAACGTATCACAGTAATATGTATCGCGAGTCTAGGAACTTGAGCACCCAATCATCATCCGTGGCGTCTCCGCGGGCTCTGAACGAGAAAACTGGGCACTCCCGGCTACTTTGAAATCAGGAAAAGGTCATCTGTTAAATGTCTGTTCACGATAATAGGCTATTCCACTTCAATACATGAATGACTTAGGATAGATATTCCCCTGGGCACGATGTTCTTATGGAGTGCGGGATTTAGTGGATATTCACGCTTGTATTCAGTCCCCTGTCCCATCACCTTTTTATTTGTCCTCCGCCCGGATTCGTTTCGTGCACGGCCAACGAGGAGCTGTTCATCAAATCTACCGACATTAATAAGTCTGGCCTATATGTCGTCCAACTAGGGACCCCTTTCAGAGTAGGTGGAGCTATCGTAGTCATCAAGTCACAAAATGAGTTCCTTTAAGGTGGCGATGTGTTGGGTGCAGACAGTATAGATAACACTCGGCATGGCTTTAGTCCCTCTATCTCGGATGCGCGCATCACAGATACCGCACAGGGTCCCACCTTACATGTTCGGTTGGGACTGAGTGGAAAAGTTGGACCCTAATGGTTGCTTCCGCGAGAACAGAGACTTGAAGCAGTCAGTCAGGGATTCAGTCCGTCAGATAGGGGTGGAAGTATGGCCGGCGGCCATTTGAAGTCGGCTAGCAGCAAATAAATTGCGTAAATATGTTGGTGTTTGGGACAAGGAGGCACGGATCCAGACGTTACTGAGTCCCCGAAAGCGTTACTCACGGATACACGCCATACGCTCTACTAAGAAGAACCATGCACGGACCATTCGATACAGTCTTTCAAACGCCAATGAACCAGGAGCCGGGGGGATGAAGGTGGGTTGGAGGCATCGGAGTGGTTGGGAACTGGTAAACGAGAAGGCCTAAGAGTACTCCCAACGCGGTGGGTAGTATGTAGGTTGGTTTAAGTCGCGTTATCTGGAGCCCGATACAGAAGACCATCAGCTAAGAGTGGTCGTAAGACAACAGATAATCCAGGCATACTAACACCGTTTTATTAACACCTAACCCGTGCGCGGGCAATGATCTGTGATTTCGGCGGAACCCTTTAGCAATCACTCGAATGCTCCCCTCAAATTTGAAAGGCATGACCTCCGTTGTACGCCCTGGATTTCTTAGGGATCGATTAAATTGGAGGCGAATCGTGTGTCTGATCTATTGGCCAATTTGATAAATCGGGACAGAAAACCCTGGGCAGCTGTATCCCGGCCAACTTGACTTTCACCTTTATGCTATCAGAAAAATCGGTGAAACTGAAAGTCTCTGAAGTTCTCTGCAGTCATGCGGGTACACGAATGTGAATATGAGCTGTCGCGAGTTAATAGGACAGGCAGAAGCGCAGGTTGCGTCCTAACAGGAATACTCTTAAAGTAGGTGCGAATCGAGCAACGTCATCGCGTCAAGCGCGACCGCTTCAGTTGGTTGGAGGCTGTCGGCAGGTTCATCTTGCCAAATCGAACTAGCAGTGGCTTCGTTACGGGCCAATACCACCTCGAGGAACCCGGGTAATGAGGTACAGCTTACACAGGCAACCTGACAGAATGGATGTTTGACCTTCTATGCTGTACGTGTTAGCCCAACACAATTAGCAAGATTGCACCGGCGCTAACAATGTTAATGAGGTGTACTAAAGAGGTCGTACAGACAGGTCATGGGGGTAGGCGTATTTTCGCGCAGAACACGGGTCTATCCCATGAACGTACAGGCAAAATATTCGTTCTAGGAGCTGTGGGTCGGTTCCGTGGAGAAAAGTCGCAAGGCTATGTAAGCATTCATGCCTAATCCTCGCAAAAAGTGTGTGGGATTAGAAGCGTGTCTGAGCAGATGTGGTGCGGGATCGAAATAAGTAGGTAACTACCACAGCACACTATTCCAAGCAATAGTTCGAAAAAGGAAGACAAACCGATTCGGTTAAACTTGTGGCGGTCCTTTATTGCGCTAGCGTGCACATACTTATAACCGTTCCTTGCTAGATGCCAATACACGATATTGGCACATCAGGTGCTTTCACCCGAGACAAACGGCCTCTGCTAGCAATCCCGGGTCGGTAAAAATAGAAGACGAGAGGACGGCGATCATATCGTGCGAATAGTATCAGGCTTCATATGGGCAGTTCGCCTCGAGGACTACCCTCGTCGAAAAGCTTTACCGGAAGATGCCAAACCCGGGCAGCGGCACCAGGCTGTTACCCGTACTCCTAATAGCTCGGCTAAAACACGGAGAATGAAATACCTGTACCAAACGCACGTTGAGCTTCATCCACCTCTGGCGTGTGTACTATCCTATAGCGGATTTCGCCGGAGTTGCCTTTTCTCCTTGAGTGTTGATGCTGCCTTCTAACAAGCGCCTTTGCACCCAACATCGACATTTAAACTTTATTATGGGGTTGGTCCTGCTCCGTGCAACTGTCCTCTCTGTCACCACTATATTAAACATAGTCTGACCTAATGCAAGTTAGTAAGGAACAAGAGCAGCCTCATAAAGACTTGGCGACGCGTTGAGACACATATTGGGTACTTTAGGGATAATAAGTGTGAGGTACGAGGTGCGCGGACATTATCTTGATGCCCTTCTTGGAAATGTCGTATTTCAGGCCCCTGGTGCGGAAGAACTTTGGCCGGGTTTACATAGTTTAGATAGTCCTAGGTACATCAAGACGCCAGTATGAGTCCGCGAGCCGGTATGAGTCATATACAAGCCAAAGGGCCGCCTCCAACTTCTGTATCCGTAATTTTCTCCATAGGGCTCTGACCAGTATTGACCCCAAAATGTGGGCTGCAGATCCAAAGAGTTAACGGTACTACCCGAGGGATCAGTCATTCACTACGGTGCGCCTTGGATGGGATCCTACCGTTGAATTCGTAGCCTCCTGCGCTCCGCTAACCCTGACAATATGTGCACTTCGCCTGGACGTATTGACACCTGAAACGAGCACTGAGCGTAAAGCTAGTTGTTATACGTCACTGCACCATGTGGCGGGTTATAGCATCCTCCCATTTAGGTAATGCGAATCTTCACAGACATGACGGGGCATGTGGACTTACCGGTTACTTCGGGAAAACTGGCAGACAAAGGTTGGTTATAACCTACCAGCAAGTCATAATCTGTTTCAGGAATTACGCAGTTCTGCCGCTCATCCTAAAAATCCACCGACCCTCGCACGTGCCGAGTTAATCTACGGAACGCATAAGAGAACGGAAGCCCAACTGGAAGTTGGACAATGCCATGAGCGCCCTCGGACCACCCTCAGAGAGGTAATTTAGGGGAGCTAGGTAATGATCACGCTTTTCAGTGGTCCTGTATCGTGCATAGGGAAACCACTCTGGATAGTGCTTCTAGCGAATCGTCTAAGTACCCCATCCTTATAGCCCTGCCAAAGTGCTGGTAGTAGCTATCCGGATCACCACGTTCGGGGGACGGGGCGTGGCTCGTCCGTATGCTGGCTTCGCCGTAGCGCAGTCCGAAAACTGACAGACATAGTGCATTAGCATTTAAACCACCTCGAATAAGATTTGGGCAGATAATAGCGCCATCGTGTGCACTTGTTGCTCGGTGCCACCTAACCCCGAAGCTCCTAAGGCGCGGGCCTATAATCGTTATCCCCTACGAAATGCAAGTGCGTCCTTGCTAGAATCATTTGACTCTCCAGGGCCGGGAGTGATAGACCTTTTCAGATGTGTACCCAACGATGGGTTCCTACTCACGTAGATACCAGTTCAACCGCATAACCGTGAATTTTGGTCCGTGTCGTGGACGCCCGGAATGATAAGCCTCAACAGATTGCCTGTTTAGCTGGTCGATTGTGCCGATCAAGTTGACGTGCTAGGCCGGCGCTAAGCGTAGAGGAGAAATCTCGCAGCTTCGATACACGCGAGAACTTGGGCGTCACTTACATAGTCGGAGGTGTCATGGTTGAGCCGGTATCTCCGATTGATCACTCGGGACCAAACTCTATCTTCCTTCTAGAATCATCACGCCGACTTGAACACTGTCGTCGTTTATCACTGATAACGCTTATCAGGTTACGTGGAATCGAAGGTTCAAGACGGTCATGGAGCTGTTTTCTATTATTTCACTGTTAGTTCTTGGATACTGGCGAAGGACGCGCCACTTAGACTGTGCAGTCCCCAATTGGCTCGAGATTCCATCGGCGCGTCTACCTGACTCAATGCGTTACAGTCTTGGCCTGGCGCTCCTACCCCTGCGGCCTATAACGAGGTGGCTGTCCCGCGTGCAACACTCGCGAGCAACATGCCAAGACTTAGGTATAATAGCTTAAAGGTGTTCGCTTCTTGGTAGATAATTCTGGATCCGCGTGCCCACCTCCCTGTGCTACGAAGTTCCGTGAACAATGTCTAGATGTATAGCAGTGTGCAAGCCACCAGGTTCTATGGTGAGCAGCAATACAAGCCGTAGGTGACGTTCGGAATGACCCGCAATTTGTCGCGCCCCAGAGTAAAGCGAAGGCTTGACACTCCCGACTAGTAATCCCATGTGTAGGCCCCAGCACTAAAACATCTCGTTCCTCCTCACTTCCTGTGCTCAAGCCGCCTGGGGTCGAGGCGTAAGTACGGTCTTGATTGGTTGATTTTTGGACAATATGATGTCTCTACCAGCAACGCCGCCACCGGTTATGTCAGTCTCTGAGTTATAGCTACAATCTCAAGAATGTCGTGCGGCTCCCGTGGATGGCAGACGAGTCAAGACCAATAACAGACGTGTGGCACCTCTGGTCGTATCGTCACCCCCAATTGATGAAAATGTGGCTAGAGTTCCGAGGAGGACTTGCAAAACGAGTATCATTGATCCAGCCCATTACTCCAGTGTCCAAGCCCGAAACTGTAAGAGGGCCATTGAAATAATACCGGCTAAGGAATGTCTCGGGCGTGCGGGAATCATAAGGATCCCTCAGTTGACGATTGGGCGCCTCTTTTGCGAGCGGCATCCGCTGCATCGAGGTAAATATGTGTTGGGGACACAAGCCGGATTGGCATTGCCGGAACTTATGTGCGGCAATTGCAAAAGTCGAGTACTAGAAGGATGATCAATTGCCGATGCGCCAATTGAAGATGATCGCCTAAATTGGCTTGTTCATCCTTCGCTCCTGTACGAAGAACTCTATCCAACAGTTGATGGTTGGCAGTAGTTCCGCACGAACAACAACGGGATGGAATTCACGGACATGTTGGTGCCTAAACTAGCGCCGGTTTACCGGACGTGTCCGTACTCATTCCCGCCGCGCCAGCCAGAAAGGGTCGATAATTGCAACCTCTCTCGCAGTATCCTTTGGTCGGCAGAACGCCATGGAGCGATCTCCTATCTCTCAAGGTCAGTTTAAGAATTATGAAGTACTTCTCGACGTGTTGAACTTCCGGTCTCGGCCGTTAGGCTCGCTCGATTGAAGTACAACAGAATTCAGTTTAACCTACTACTCGCCCCAGAGTACTTCCTATGAATGGCTGAACTCTGACACCGAGTAGACAAGTGGTGGATATACTCTTTACGGGAGTCACGTATATCGTACTATTATGTTTCAACGGTGCTTGCCATCCACCACAACACCGGTAAGATTATCAACGCTTACTCTCAATATTGCCCGCGAGGAGGTCTTATCCAAGGTGTAACAATAGTAGTCTGTAGCGTTGAGATTAGTCTTAGAAACGGTGAAGGGCGTTCTCGTGCGCTCGATACCGCTCCCCCCCAATCGTGTTCGGCATCACTAGGACATACAGCGGTCGCCAAAGCCTTTCACCGGTATCGCTTCTCGGGACTGATGCTGCAATACACGCGTAGTCGAAGCAAATTTATGGTGCCCAGCATCTGAAGCAACTCCATAACTTTTACCGTCGATAACAGGATTTGGTAGTCCGCTCGGTACTAATGCCGCAAAATGAAGCCCTATAATGAGATATCCTAAGGACGTAGGGCGCCATTGTTGGTTAATTCCCCCTACGGATTGACGGGCCGCGCCGTCGGGCTGGGGTTCGTATGAACCTAGCTCCACGCCAAGACCTGTCCCTTGTCATAGCCAACAGGACACCTTTCATTATGGCGCTACGCATATGCGACTGTTCCCACAGTACAATGATGTGCTTAACCATCGTCGCTCGGCGATAGGGTATCTTTTAACTATCTTAGACTGATAACGTGTGGGCCGATAGTATCTAAGAGCTGTGAGGCTTGTGGACCACTTAAGCTATCGACTCCCATTGGGGCAAGTGATTACCCGGGTGCTATCCACAAGACCGCACTTGTGTCCTTGCGTCGAATTAAGAAAGCTATAGGGACCAGCTGATATTAGGTGCTGAGGAGTGCTACCGGCCTGTTTCACATATATCAGAACGCGTGCCCTGAACTAAGACTCAGCCAATCAATACTGCGTTGTGGGTGAGGCAAGTATTCTGTCCGGGGATGCTGTGGGGGACAGTATTGATCTATCATACTAACCATAGTCGACATCTCAGGTTTTCGAGCGCTGACGGTACAGACAAATTTAGGGCGCTACGAGAACAGCATGTCGCTTGAACCGACTCAGGCGCCGTAATTAAAGGGAGTGTGCCATGAACTCGAACGCACTCCGTATCAACGCAGAAACCGCCTTACAACACTGAGCGGCGTAAGAATACTCACTCGATATTGATTACCGTAAGGCTATATTTGTATGGGAAGCAAACGAATGACATTTCCTGGATATACAACAGTTAGCTGAAGGCATATGTGATCTGCCAGATTCCAGAAGCTGATGGGGGATCAGGATGAACCTTGTCAAGGATTCGTATCTGCGCTATACAGGGAGAACTGTGCGATTGTTGAGGCTACGCCGCGTAGCCGAGCCGTTGGAATAAGCAGCCCCGTATGTGGACATTGGTAGGAGCATATTCAACGGGCCACTAAAGGTCGCAATTGCCTACATCAGATGAAAGGTTGTTACCGGGCTAATATCATATAGAGCCCTCTAATATCCACCTGTTGTATGAATACTGTCGCAGTTTCATCACGGTTGCCCCTAAAACACTGACAATTAGGTAGCGGTATCGTTTCTCATCTACTCAAGGCGTATCTTGGGTCGCAGGGGCACGCCGTGGTTGCTCGCCAGTTACTTACTGACGGTACCTCTCATTCTTTGCAATGCGGGTACTTGTGTCGTTGAAAGTAGTGGTACTCGCACCAACTCAATCTATCGCCGCTGCGAGACAGTCCCCGAAAGCCTCCGCAGGAGCAGCGCTACCTCATATCCTGCACGATTAGAATTAACTGCCTCTCTAGAAACGAGTCTTACTAGTAGTTGACCTTGATTCTACGGCCACTCGCATCGCGATGATTGAGAGAGTTCCCCCACTCACGAATTAGGAATCATGTTGTAACAGCGGTCCCACTTGAAGGTGAGTCTCCATACAACGAGTACATACTTGAGCAAGCAACTAGATTATCAAGAACACGCATTTGTCCTAGCCTGAACCACTTTTGGTCTCACATAAGACAGCGGGAGAAGCGATTCGGGCGACGAGGCTGTTAAGTCGCACGGGTTGCTATTCATATAACACCTCGCCGTCGTGTTAATGATGTTTATGAGCCCTGGCGGTATGCAGAGCTAATTGGTTTGCATGGGTGAGGTAACTTGATTCCGTGTTTGGTAACGAGCGGCGGTCTACACCTAGTCTCGGCCATTGGAGACTGTTCGCGGGGGTAAAAAATCAATTATACAGACACTCTAGCCTGATATTGCCCAATTTGAAAGAGTTCAACCTTTCGCAGTTTAGTGAAAACTGAGCGGTTTGTGAATATTACCGGCCTTATATATCAAATGGTCCGGTACCAAGCCTAGACATGTTCGGACTTTGTTCCGTTAAAACCGAAGATTACGCATTTCACGACTCTAATTTTTAGAGACTGCTAGACAGGATATCAGCCACGGTGCGTCCTTCCTGTATCGCTACGTACTTGCTCCTCGCCTTCTATATAACGGTACTGGCGAATTCGACAATACCCTAATAGGAGCTGCGACTCTCTAGACGACCAGCATGCAGCTTATTTAAGTCACACAGATCGTAAGAGAGCCTCGCAATGCTCAGGATATCGGCTGCCCTAGAGGATTAGCGGGAGTTGGCTGGCGCTATTGAATGTGTCAGCAATGGCAGCTCCAGGATCGTCCAAGGAGCCGCTGGCCCGTCCCATATGGTCTTCGTATCAGTACTGATCAAAAGGCGCAGCGTGAATACGTTTTCCTCCATAACATCCAGTCAGTAGCTGATAACGTTCTCACCCACTGACTTCCAACAGGGGCGATGGACCTCCAGGCGAGCCATGGAGTTCGACCCCCTTGAGGTATAGTGTAGGAACGGGATAGGGATTAAAAGCGTTGTGGTTTACTCTAAGCAGGCTAAGAGGCATAATGTCAGCCCATCAGCGCGCGGTTAGACCTAGCCGATTGGCGCGTACCAGGAAGCCGTCCGTCAATTTACAATTGGTCGTAGTCGGGATACCATCTTGAAATGCGTAGTCCGTCGCGCTTCGGGGCGGGCTTGAAGTGATCATGTGCACCCTTTAAAGCCATAGCCATACAACGTACCTCGGCTGAGTAGGTTCATTCTCTTGGAAAAATACCGCTAAGATAGAGACACCTAAAGTAGGCTTCTTAATAGGGCATGTGTTTCCGCCTAGCGTTGACAGCATGTGATTAACCACTTGACCATCTGTCACGCGTCATGCTGAAGCTTACCCTTGATACACGGGCCGTTATCCAGACGCCTGGAAACTCGAATTCATCAAAATTCCTCCATTTCTCTGGCCCGACAATCCACTGTAGAGTGGGATCGGTGTAATACCCTGAGTTTTCTAAACGGCGACACCGATGCTATTTAGTATGCCACGCGCTTCGTACTGTTGAAAAGCAATTGGAACTGGATGTCTATCCCGTACTTTTAAGTCGTAGATCCGCATCATCCATGCTAATCGTCGTCATTAACCAATCACAGTCTTGCAAAACTCACACTGGCTGATTCTGTCCAGCGTTACCGCGGTCCTGTCCGATTAAGAGCTCTCTCTGCCTATTTTCAGTTCCCTCCAGGCGTAAGGGACTTGATGTACACGCTCGACGAGTGCGGCTCTCTGTGACTAGAAGTCACTCGGGCTAAAGACGACTAGAGGTTTTTTCTGCGATCTAATATTAACCATACCCTACACAAACGCCCACCGGTTTTTATCACAACCACAGTAGCGGAGACGTAAATCGTTGTGCACAGAAAGTTAGGTAAGTTATCAAAGGGCAAAAGAATTACAGGCCATATTCTTTCAGTGTGACCTTCGAGTGCGGATTAAGTCCGCGGCAAAAGCCTAGGGACGACATCTTAGTAGGCTATCTCCACCCAGTATCTGGCGCGACGTCAGGTGTCAGTACCATGCTCTTATGCCCCCCTTTAGGTCCACCTAAACCTCGAGGTCAGCGATTGACCCATGTAGATACTGGTAGACGTCGGTGCCACTATGATCGGTTTTGTCGTAATTCACGAGCATTTGTCATACTGTTAAAAACAAACTTTGACGACAGTTTGGTGCTAATTTGAGAACCCACGTGGGGCCTGCCGCCGGATGTACGGTATGATCTCACCGGGTCTCCATGATACCCCCATCAGCCTCATGTTCTGGCCCGTCCTCAGAAGCGAGCCCTCAGTCCTTTCTTAATCTCCAGTTACTTATCAGGGAGTCCAGAAGCTCCGGGTCTTCCAAATCCTCCGCGATGTCTTAGTCGACCCTAGGGACACCTAGAGGATAGTCGCATTTGTAGTGTAGCTGTCCGAGAGCAGAACGCTGCGGCAGGCGGACATTGAAGTTACGGCTATGTTATCAGTCATCCTCGGCTTATAAGAGGCTTTGGGAAAGTTGGGTTAGTGGCCCAAACGATGATATGCACCAACCAAACTCTTTCACAGCAATCCCGCAGAATAATTGCGGCGCGGACGGGCGATGGGCCAGCTGCTAGGGTAGCGACAAAAGGACCACCAGCTTCTGTCTGAAGACAGGGGCCACCAAACCACCCTTGTCCAACTCGTATGCCCGAACAAGAATCGAGATCGAATTGTCACTTATCATCCCGTACACAGTAGGTCCCGTCTACGTATTCCATGCGTTGCCGCAGGATTTACACCAAGTTTGGTCGCCGGTCCTCACTCGCTAACTACAGCTGTGTAAAGCGCGGGCGAGGGCGATGGATACGTACCCGAGGTTATCAGGCTGAATTGCTGGTGAACACTTAGGTACGACTCATACGCGGGAACCCGGCAGAACTGTACATTCGCGGTTTTTGTCCTCTAGCTATTTCCAAGAGCTGATCACGAGAAGTCTCTCCACGCACATCGCTGAAGCGAGACCCTCGCCAAGTGTTACTTATAGACTTCTATGCGGCGCCGCAGTTTATACAAGTCCTCGCTCATTTTAGTTCGTGCCTACACTGTCACTCCTACGGTACGCCACGGCGCGTGGTGATGAAAAGGTTTCAAGTTCGTATGCGAAAATACAGGCCATTTAACACGGACTCCGCGTCCGGGCGGGGCCGTAACGTTGCCCGTACCCGGACAGTTCCATTGTGAAGCACTACAGCTTCAATGTTACCAGTGTAACGCCAGCATCAAGAGTTGCAATGGTCTAAGCGTCACCTGAATTTGCTATATCCTGACGAGACAGGCGTGCCCCATCGGAATGGCAGAGGTAATAGGCAGCATCCCCGCGGATCTTCATCTGCCGTCAACAGCGCCGGATTTGTAGGCGGGGCGATAAGCACTCGGGGGTCATCGTTTAACCACCAAATGGGCAGTACAGGTGTTCTCCTGTCGGGCCGTGTAGTTAGTCCGACAGGTGAAACAATCTGTCAACGAATTGGCGCCTACTTGGTCCGCCAAGTGAGATCTTGAAATTACAAGTCTTTCCGGCGCAATCAGGCCACGATACTGGGGCAACACCCCGTTGGGACGACTGGTAGAAGCTGGACTCCGGGACGGGGCACAAGGCGGTGGCGGCATTGAACAAGCACGCACGCTCCTCCCTATACCTACGACAACTTAATCTTGTACCAGACAACCTAGGAACCCTCACTTGACTGCTCAAGCCGAAGGGAACAACCCCCTCCTTGGACAAAGCTTACTGCCAAGGCTTGGTACGTTCGCGTGTCCGTTCTGTATCGGGACCTGAATTGCGTGTGCAAGCGTCATTCGCCATGGCCACTACGGCCTGGTCGGGCACCCAGTGTGATAGTCTTTCATGCGAATGGCCCAGTGCTATCTTGTTCGCAACGTTCTGTAGATAGAAGGCCGTGGAAACTGCGACTATCCGCCGCACAACCTTCACGGGCCCCGCCTCTCTATGGAATACGTGTCTCATGTGCGATATGAAGGTTGCCCTCCATAAAGCAGATAGTGCTGATGTGCACTACTTGGTACTTTGAAACGTATTAGTCTCACCTGCTGATGATTCCTTTAAAGCGGTGCAAACAGCCTTCGGCAACCGGCCACTTAGGCTCGACGGACACCATGCCTTTCTGACTTACAAAATGACCACGCCCCTACGACAGCTGTCGTTACCAGGCATGCCTTAGCTGTCAATGGCCTCATCCTGCCTCCTAAGGGGGTATGTTCTCCTAGTAGCCATGTCATAAAACCCCTGCGCGAACCGGGTTATCTACGAACAGTACGAACCCGGCGCGTTTTGGCTAAAGTGGGGTTTATTCAGGGAGCCCGACATACCACAACAGTAACAATAACACACTAGCCGTTAGCAGGGTCGACGTGCTCCCGTTCGCGGAATTCTGGCTGAACGTAAATACGCACCTGAGCGAATTTTCCACGAACACTTTTACATTTAACCTCGCAAGAACCCTCCCCATTAACGAGCTGAAACGCTTATAAGAGAGACGTAATGGATCAGAGACCATCTCCTCCGAGAAAAGTCTGGGTGAATCTACGATGGGTATCTGGAACCATGCTCCCTCTTCCGGAGGACAAGCCCTTAATATGGAATCCAGACTAAAGCCATAGCGATAGCAGCTTAAAACTAAGGCACGTCGTCCAGCCAATTCGGCCGATTCCGTTTGGAACAAATAGCTGTCTGTCGCAAACACGACCCTGGGAAATGATCCAGTTCTACCGCACCAGAAGCGACCCACCCCGTATTCGCGTGGTGTTCCTTCAAAAACGCCCCCTTGGGACTCAAGACGTCGAACTTCTTTACCCCAACCGTTGCGGGGTGTGTGAGAAACCGCAGACTTGAGAGCCCGAGTATCTAATGCAATCTTCTCGGGTAACAAGTGTGTGTACATCGTGACAAGTCCTTGGGGTCTGCAACAGTATGTCCGACCAATTGACCGACCGCAGCATAGTCACAGTCGGAACTTTCGGAGTAAATCCAGGAGGGACGCCTATAAACTGTTCATAGGTGTCAAAACGGGCAAGGAACCAGAGAATGATTCAGTGCATTCGAAGAGTGGACGCGGTAACGACGTATAAATTTCGCGCTTCCAAGTAACACCGGACCGCGATGTGTGTCGCATACCGAGTTCTATGACGATGCTCAGAACCTTTGTCCACTAGCTTGCAGTTGCTCGACCCTAAGCGTTGATCCGATCTGTGTACAGAGAATCCACTTCTTATCTCCGTTGGCCATTAAAGCGTTTGTGTCCAGATCGGACTTGGTGTGTATGTAAGGCCTGATACCGCACAATAGGAAATATATCGGCTAAATTAAATTGGCTCGGGATAGCCGATCTCGAATACGTCCATTACTGAAGCAATTGGTTACGCGCGAGCCCCCGATATTGACTTTGATAGTATGTCCAAACGAGTACAAACTCGTTGCACTTAAGTTCGACTTGCTATGAAACATAGCCGTAGGAGGATTTAACCGAGCCACAGGCGGCTCCCTCTATCTTAGCGGATCGAAGTAATATTCTGTTGTCATGGCTTTAATTGGGAAATGGCTGCCGAAATTTGGCGAAAGATAACAAGTTAATAAGGACAATTCCTACTTACCAAGGGTACTGTTTCGCAGCGGCCGGTACCCCTTCGAGACTCTGTTGATTTTCCGTGTACACAGGCAAAATGCATTGTATATCCCGGATTGCTTGCTGCTCATTAGGACTTTACGACATTAAAAGCAGACCAATTTGACCCTGCTAACCATTAATCAAGGTAAGCTGCTCTTTCACGGAGAAAGCGCGTGTCTGACTGAGTATATCTAATAGAGTTAGCGTACAGTAGTGATTGGCATGCCATCGAGAGGCGACGTCCGTAGTCAACCTACACCGTTAGAGAACCCTTGTCCGTTGCGCTTCTTAATCTTTTGTCGAAGAGGAAGTACATGAAACAATCAGATTAGTCATTATGATACACATCGGTTGGGACACATAATCTTTGCGCTGCAATACCCTACAGTGGCTGAAAGAGTGGCGTTGCACGCGGACTAGGATTACAGCGTATGCCCAGGTTCTTCGTACGTTCCTATGGGGCTGTAACTTAGTATCAGACAAGCTTGCAGACCCGCGCCCGGGCACCGTGCTATCTGAGTGCATGCCGTCGGCGTAAATCGTGCAGTGATTCTCCTCCGCCAACGGCCCTGAACAGGGTTCGGTGCTACTACTGTGGCAGGGGGGCGGGGTGTATGTTACCACAGAAACTCCTCACGCGGCAGGGTTGACGGCCAGTATACGCTATGAAAGCCAACAATTGGAGTATGAATCCCTCACGAGGCTTAGCGATGCAGAAGCTCGCCTGTAGACTAGTCTTACTAAGTGAAGAAACGGCGGACGAAATCGAACGTGGGTTATGCTTCGATAGTCAACCATGAGTGCATTCAGTAGAAGGTCGGAGAATCCACTAGTGTGCGGAATTATGGGTTCCATCTAAGGCGAGAAGGGTCCGGGTTAAGTCCAGCTTCTACACTCAGCAGGCAAACATACGTGGCCAGGCTCCTTTTAATCCCCGGAACAACCCACTCCGGGGGGTGATCCCGAAAGATAGATTTATGTTGAACAGGCAGTAGCGATTAAGGCAGCGGGAGTGGACATATATAGCAGCAAATTGTCTCCCTCGGGCCTTAGCTCTAGCTCCGGATAACATAACATACCTGTGCATTTGGCAGCAATGATGATCTTGTGCTAGGTTGACACTGGTTGGCGGACAACGCCCAGTAATGGGACTAGCCTGTGGCAGTTTGAGTTTATGCGTGAGCACAGAAGCGCGCCCGTCTTAGGTTGCTTCACACGGCCGATGTCACGGCAAATTGGTTTCCAGGGAGAGATTGACGTGTCTTGAGTCTACGCTCCGCGTTAAATACACCCCCCCTGACCACGTTATTGTGCGTTTAGACCTATTCAGTTCAAGGCGTATGGGAAGACAGCCCGGTAACGTCGCGGTCGATGTCGAGATCCGCTGCGCCCGTTCATAGACGACAGCATGAGAATCGACGGTCTTGAACGTTAACAGATCTCAAAGTCGTTAGCATAAAGCTCCTAGACCAGTCCGTATTGCCGAATGTCCTTAGACTGATAGGCTATGGCTGCAGACTCACGCATCAGCCCGGCGGGGCTTCAGCGATCTAAAGCTCGCTCCGAAGAAGCTCGGGATACTCATGAAGGGAACTTGAAGAGTTATATCGAGCACGGAGAGACCACACATAGCCCTCTATAGATTTGTAAAATTAATGGGATTGTCATACATGCCAATGGTATGGGCTAGAGGCGCCTGTCAGTCAAGGAGATAATTCGTACTCCCTTACTTCAGGGTAGATCATGACAGTTCAGGTGAGGTCATCTAAGGAAGGTCGCTCGGCTGTAGGGGTCTCGTACTATTAGCCCACCTCAGCCCATCCGCCTTCACTCACATATTGTCCCCCTGGCCTAATGGAATGGAAGGTGATCACTCTGGTCGGGTACTACCACCATATAAACACTGTCGCTGTAATTGTGTTCACTAAATACGCAGTCGAACGTCCCCAGTCCACGTCCGGGTGATGCCGCGCTCCCAAGTGGAAGGTATCGATTTAGGAACCATCGATGCTAAAGACTGTATCCTCGTACGCAAGCTACCGGGAGACACCTCCGGGAGCAGTGTCGGTACGCTTGTATAACATCCTGACAAACGCGTTAGTTGAACATTAGGCGTGGTTCGCAAGGTCGGCACTCGCTGAGACAGTGTAAAGTTTGGCGGCTCGTTACCATGAGGCCTTTTCTTCTTGGGAGGTGTTAACCCAGGGCGTGTGCGTATACGCCATAGGACTTACTAAGTTGTGGACACCCGCCCGCCTTTTTAGTTTTAATAATGCCCGGCACCTTTGCTTATGCGATTGCAACATCGCTGCAATAAGCTCGCTGGACGTATCAGGCCGGAGAGATGCTATCGCGAAAGGATTCTTCCCTCGCAGCGCGTTCGCATTCTCATTTCGATAGAGCTCGATTAAATCACGGAACGCTATGGAACAAGTGTGCGGGACCGAGAGCAAAACGCACGTGTTAGCACCTTGACCTAAGAATTGGGGATAAGGATAGCCGAATGAATGCACTTAGATGCGTTTCGCCGCCTGCTACCACATGAGCTGAGACAATTAAGCGCAGAGATCATTGGTGCTGTCAGTGCAATACCTATGTGGGCCGCCTTACACTAATTAGACATCCGCAGCCGCCCATTTGCGGCACGAAGGGAAATCCGTTAAACACGGGCCGTCCGAAGTCCACAAGCACAGGTCCGTGACCCGTGATGGTTCTGTTTTAAGCCATCTTTTGGCGTTCTGTCGATGAAATGCTGAGGTTAAGTGCGCGAAGTTGCTTTCCGACGAGACTGCTCCCTGCCGGCGGGTACGCGTACAGACCCTGCGGTCCGCGGGCGTGATCTAGATTACAATCGACTTCCACGGCTATCATCCGCTCGTTTGCCATGGAGTCGTGACAACCAGTCTAATTGGGCTATATCCCCTGCGCGAGTACTCCGCGGCCATAGGTATGCGTTACAGCGTTCCGGAGCAAAGCGTGCACTAGTATCTTCATCCATGAGGTAGACGATAGGGGTGGGATCGACTCCGATGCTAATGTCTAAAGTCCCCACGCATCTATGTCCCATAACACATGACCTACAGACCTTCTGTTGTTAAGATGGTGTTTGTCCGATGAATCGTAAAGACTAGCTGACTGTACGCAAAACTAGGTAGTTTGCTATCTGACCATGGGGTTTGTCTCTGTCGCTTTCGAGGGAATAATTAAAATCCGGGATGCGGGTTTCAGGCCCACGTAAGGCATCCGACTATCTACCAGCATACACGAAATTCTAATGAGTTCAGATGCCGTCTAAACAGCTGATAGTGACTGCCATCCTAGAGGACTCGCTCTCTTCTTACCCATGAGGTACTGCGTCGGAGTTTACTGACCACCCCCGATCCAGCTAGAGCGATGAAAATTAAGTTTTACGGACCATAGATGGGGTGTATACATTTACAGCAAACAATCGCCCTTGCTCCTAGAGTTACATACACGCCTCTACGACCTGCCAGCCAGATCTCGTTATCGCCCAAGGCAAAACTTACCGCAACGCGAGGCGCCTTTGGGACGGCTGCCTCATATAGCCGCCATACACATGACTACCCAGCGACGTTTGTAGAAGCAATGGGCGAAGAAGGACGATTCGAACACTATCAGGGGTGCTTCAGTTTACCTGGAAACGACTTTCTCTGCGATCCTATTCACGTCCTAAAGCATCTCCGCTAACTCGACGTTGAGATGAGCCATTGGGCTGGAACAACAGTCAGCCCCTAATGAGGCTACCTCGACCAGTTTTGGTTGCAAAAATCCGCCCCCGGCTCTCCTTACAATTTGCGGTCGCTTAGAGACATCATTATTCACGGTCGCCAGGATACTATCCGTACGAGACCTATGCGTAGATTTAAGACCCGGCATTCGTTTTTCCGGTGTATAATGATTCAGTTATTACCATCCACATCTAACATCAAGAAAACCAGCAGGCGTGATCATGCTTTAGGTGGGTCCAGAGGATGACGACAGGCTCTTGCTTATATCCGTTCACTACTGAGGTCCCGGGGACCCACATAAGGAGCATTGGGCAAAATACGATTGCAGAAGGCCGCAGCTGTGCTACCAATTCTTGCCTTCCGTGTTTCCCTATCACTAAGACACCGCAAAGTCCATCAGGTCGAGTCATCCCCAGCCGGCAAGCAGATTCAGGTAACTACACAACCTCACTGAGCAGCGACGGCTTATAAAAGTGCGTTTGTTAACTTAGGTCTTTAGCTATAACACGTGGCTGATCACACTCATTCATGTATCATCGGCGCTAATGCGGCAAGTGGGAAGACATCTAACCGAGGGTAAGAGTTCTATCTTAGATCCGGTATCGTCAATACTGACGCGAAGTTGCGGACCATTGGAGTGCGCGCCCTCTGGCTGTTTGGGGTATTTCATCTCTGAACATTTAAACATGTAAGAGGTTGAACGATCATGACTCCAACCACCTTCGCCCAATTCGAACAAGTTGACGGCTGTGTGAGACCCGCTCATAATACCAATAAAGAAGGTCACAAAGCTTAGTGCACGTTTGATGTGAGCCCAGCCCGCTAGAGGCCTGCTAAAACCTGCAGCTGACAGGGGCGCCAAGACGCGAATCTGTTGTATTACAAATCAAAGAAACCGACACATTTTAGACTACGAGCCAATTACGATATCGGGCCCCCTTCCCGCCGAAGAGTTTGTCAGTCACATAATGATCGTATGTCACCGATACCCCTGGAGGGTCCAAATATAAAGAACAGTCATTTGTAATCTGGGAAGTCACAACATTTATGACAGGAGATAAGGTTATACAGCCTTGTAAGACTCGGATGATAATATTCGCTCTATTGACTGGCAAGTATTGCACTATTTGCGAATTAAGAAACACCCGCGTCCCAGCTCGACATTCCCGAGTGTTCATTCCTGGTCCCATCTTGACCGGGTATGGACTGGGTCCCTCGATGAGCACCTGTTCGCTATCATGTGGGCCGATACATCACACACCCTGATCAGGGGAGTGCCGAATTTGCACCGTCCCTGTGGCATGAAGTCTGGTGCACCGGTTACAGGGATAGCCATTGAATTCAGGGCCTCAATGTAACCAGTAAGAGCAGTGGGAAAATGCTGATGAGTTCGGATGTGGTTGTAGTCGACAGAGTACCGCGCATACTGCTTCTTGAAACGTCCGCGAGGGGATATTCGGCTTGTCGGATTATGGAATGGGATCTCATAAATCTTGAACAACGAAACACTACATGCGTCCCGACCGTGCCAAGTCATCTATTTAGAGTGCGCTTAATATATCGTAAGTAAGTCTGCAACTGTTCCGGCCGTACTTCTTTGTGGTTCCTCACAAGTATGAACCTTGTGCTCTATTCCACCGGAAGCTGGTGACTGCAATCAGAAATCGACCTGTTCTCGTTGACTGCACCGGCTGACGCTTTCATACTCTTATACGGACGAATGAATTTCTAGTTAAAGCCGCGACTTTTTAGGAACAGAGGCACCGGTTGTATCTTCGCCCGGAAATATTGGCAGCTTTTGTTGCGTAGTTATGGCCATACTAATACCGCCTCATTAGTCTATATTGTTTGGGCACATATATCATCACGCGTACCCGCCCAGTACTAACCATCAATGGCCTCTACGAGACAGTAACATTTTAAGACCCTTAGGCGACTCAAGAACTTCTCAGCAGGGTTCTCGCGAGATCATAATCTATTGCGGTTTCGTTAGCCATAGCAGCATCTTGTATTGTTATCATGTCAGGTATGCGCTCTTGTGAGTCTGACGAGTGGTCTTGTTAGTCGTTTCCACCGCTCGATGCGAGTGAGTGCAGACCGCTTCATGTTCTTCGGTTGCTCGGAATGGAATGGGGCACGCAGGCGACAGCCTACCGTCCTGCCTGGCGAGGGAAGATTTCAAAGTCGCTACCCGATCTGGGTTGTTTCTTAGTCGGCATATTGGAGGCGACTCATAGAACGTTACTTCAAACATGGGATTTCATAGTTGTTTTAGAGCCGCAAGTCTTACCACACGATTGCATAACTTGATCGTATTGCGAAGTTTGAGTCCGGGAAAAACAAACCTCTAATGATAACACATGTCTGCCGGACCGCCTTGCAGTTATCACCGATCCGGTTCATAGGGTAGCCAGCTTCGTATGACCTTAGCCGATTACTGTAGAGGCAATTGCAAAGTCAAAGCGAAATTCAGGCGTACCTCAGACATAAACGGGAACCTCGTCAGCAAGATCGGTAGACCTAGGCTACTCACGCAACGCGGTATATGCCCGGTTACTACGCGACCACGTGATGTAACCTGCTGTGTTTTACCTGGATTGCCATCGCTGGCAGATAAGTATACTAGTGATCGTGTATTCAGCATTAGGTTATTTAGAGAGAACCATCCACGTCAGGTTATTGTTGTTAACATCGTGTCGGGCTCCATCAGAGATATCCGATCTACCCTGTCAAACAACGCGAACACGAGACAACTTTTTGCGGCGCCATTTGGCCGCCAGCCGCAGGCCCCCAACGTGGTCTTACCATGAAGGGGAAGCACTTGGACGTGAAAACTGAGGTCGATTTAAGTTTGACATACAGGACTCTACGATGACCGTCGGGTGACCAATAAGGATCTACATCTCTATTCTTCGTAAGCACTGATGGTAGTATTCCAGTAATGGGAAGCTCGCAGCCACTTTGATGCTCGTTTGATAAACCCATATCGACCAAGAGCCGGCGGAGTGGCGGTTTGCTTATCAAATTCATACAGCCTGAATTTGGTTATCAGATGCCTAGCCCCTGAAACTGCAGCTCAAGCCACTGACTACAGAACTGCCCGTTTCGCCGACATCAACCCAATCGAAAGCACGATGAATCTATCGGTAAACTCATCTGTGGATCCAAACAGCATCGTTGGCCAGTACGATTTTTGCATCCCCTAGGACAGGCGGGTCCCTAGTCCGCTTGGGGCCACAGCTTGAAGGATTAGAACAAGTCGTGAGGATAGTGTTCTGTACTTTACTATAAGTATTTCGAAACTATCCATCCGTTGAGTTGACTCACGTTCGCCATGGGTTGAAGATGGACCTTCAATGGTCCAGTGTGCGCAAACAACCAGTAAACGTATTATCGTATCGAGGCAAGCGACTCATCACGAGCGCCTCGTTGGGATCGCAGAAGGGACGTAGCTGGTCACCCCAGCTATTAGGCCTGCATTGACTGCCCGCGTCATAATTCGTGCGACAGTCTATCCCGGTACTCAGCTCTACGTTATGTCTACTAGATACTCGGCTCTTGAACACCTTCCGGGCAGGACCGGAATCCCTGTTCCAGTGCACGATAAGAAGAGTTTTCGCTTCACTGCAATAAGCCGTCGATTACACAGTGAATGTAAAAAGAATGCTGGCCATGAAAGCATTGTACAACCATGCCCAGGAGGGTCTCGGACTCTCTTTCGGACAACCGCACTGGCCTTTAGAGCTGGAGCGCGGGTAAATTTCGAGGGGGTCGACTTTTTCGGGTGATTCCATATAGGCGATGTGAGACACGGAACATAATCTGTCACGATGGATGTGCCCCATGACGACCGTTGACGTACGACAACTCGAATTCAAGGAGAGTAACGAAGCGTCCGATATAAAGTCCCAACGTCTTCCGAGATCAGACCCAACTAGAGGATAATATTGTGCCAATAAAGACAGGCAAGCACTGTGGGGTCGTCAGTTTTGAGCCTAGCGTATCGGCAGAAGCTCGCAAATAAAGTCACTGACGCACATCGGGTAACGTGGTGTCCCACTGGATTTAGCATTGCAAACGGCTCAGAGCGCGGGATATCGGTGTTCTCGACTCCGAATGTATTGAGTGCGCCGAGTCGCCTCGTTATTCCGGCTTGAGTCGCTCTCTTCTGGGATATGAGAGAATGCTTTCAGCCTCTGACATCCGCCGCGCATGAGAGAGAGATGGAGATAATAGGGTGTTGGCATTCGGGAAGGGCGCTCAATGCCTACCTCGTTCCCCTCATGGTTCCCGCCTTAACTTGAGGAAAGATGGCCAGTGTACTCGGACCCCCATGGAAGATTGGTTTCCATAGATTCCAGCAGACCTAAACGCTATCTGTTCTAGCACGTAGGTCGGAAAAATAACGGCCGTAATTGGTTTTTTTCCCAATATTACAGCCCTTCCAGAATTACATATCGTCACCAACTAGGAATACAAAATCGAGCCAGATTCCCAAGCGCTCCCATATCTTTATGGTGCATTGATATAGCCAAACCCTGGTAGAGAAAGGGTGGGCGTACATCGTCAACTCTTCTGAGTAAAGTCTCAATTGAAGTGTCTTACAAAACGATCCGATATCGACTAGCTGTCTCTGTTCCTTCGGTGCCCAATAGACATTGACAAGCTGTGAAATGTTGGTTGCACTAACTTTGGGAAGCTGCTACAAATGGCATAACGATTACGACCGACGGGCTCTATTCCCTTTTGCCCCATCCTACTCTGTTATCTCGCAAATCCCAGATGTGCGACCTCCTAAACAGACAGAGTGGTGTTCCCGCGATCTGCTAGAAGCAGAGTGGTCTGGGTACGACGTACCTTCCTCGCGGAAAGTTAACGGGAGGGTTACCCTCCTGATTAAGCTCCGCGCCCTCCATCACGACTCCGATGGCCCGTTCAAACGACCCACTCGATATAACAGGACTAAGCCACCGCGCAGGGACCGCTTGACCTATCGCCAGCCCGTTGCTGGGGGAGCCTTGCTTTGCAAAATTAAGCCCCGAACCGGACATTTGCGGTCATTGCAAGGGCAGATCTACTCGTAAAGTTTCCCAGTATCGAATAGCTACGAGTAAACGGAAGCATAAACGCATCAGTTATTCCGGGAAGCTCTCTTTAACGTTGCTATCTCGGTATTAAACTCATTTTTGCCTCCGTCACTTGACCCCACCGGAGACAAAAGGAAGCGCGCTCTAGGCGAGGTATCTACTCGTAACCGCATCCACCCGAGCGTGGGTATTTGGCCTTGGTAAGGAATCTATCGATCATCTGACACGCTACTCCGGCTCTAAATAGCTTCGTTACGGGGACTATTCACAAATCACTGGAACCCATCTTTGTAAAATTGGGGGGCTGGGGCCATACTCAGTAACTAGGCGGTTTCGTTATCCACAGTAAGCTAGCTTGCCCCTTCAGTACAAGATTCAGCACTCTATGTCTCATTGCGGGTGCGGTCCTGAATGACTGTATTTCTCCAAAAGTCCTCTGAAGCGTCATCATCGTCAAGCTCCTTATCCTCTCTAATTGTCAATATTCAGATGTTGCGTCCATCGGAGCTCGGTATGGCGTGATAATACCAGAAACGTGTTAAATGAATGCTGACGGAAGCCGTTCGACCATTCCCCGAGAGTGCATGGTCGTGTGGCGACAGATCCTTCATTTACGCTACACTTTTGGCGGTTAGACCTCACCTTCCAGGTGTGTCGTGCGCATCATTCGGCGCAAATGACAGGTTTTGCCGACTTGACGCCCTATCCGTGGCACCCCCCTACCTTCGTGAGCGTTGGCCCTGCGGCACTTCCCCAAACCCTGTACATCGTGGGAGATCAGAGACACTCATAAGTACTAGCGTTGGAAGAACCGGTGTTGGCGGGTGTCAGCTCTCTCTGTATCACATACTCTGAAGTCCTACCAAGAGGGACGCTGCCTACGCTACGCCCAGGTAAAGGCATTGGACTGCTTGTTTTGTTCGGCGTCGCCCATTCACTACATCGTACCCAACGGTCTAAATTGTTGGACCAATTTGTTCCACGGATGGGCGAGCTGCATCACCTCACAGCGGAACCCCTTCATAATTCGCGACCTTCCCGCAAGGTGAGGTATAAGGAAAAAACGGCATCCCGTGCAGTCGCGGACCGCCACTGGACAGGTTCTGAGTACTAGATGGGTGTGGCCGAGAAGATCCGGACTAAAAGTCGCCTCAATCATCCGTTACCAGTTTCTAAGTGTATACGTGAGCGACACATTAGCTCTGGGTTTCACCACCAGTCGAATGCGTCAATTCAAAATTGGCGTCCTCGAACACGCTTTACGAGCGATGCTCATCGCGACACTCCAGTCACTGTTAAAGGTGTTCCGTTAAGGCAAGAGCAGCTCCACATATAACGTCCATGACATGTTGCAAGCCTGCACCATACGTCCTTTTGGAGCCGTAACCTTTTCCGGAAAGAGGATTCAGGTCAGCATTTTAGGTCTCTATTAGTGACATTGCGGATTCGCTCCGTTAACTCAAGGCCATCATTTTGGGCACTCCTCGGAGGGACCTAATTTTACTCCTACTTGCGCGATATCGATTGACAAAAGGAATTGCGTCGTATTTTCCATTGATATAAAGTGTACTTACGGCCCTGACATATCCTCACGGACACGCCAACACCACCCCGCCGTTCACGTGCCCCCCCTCGGGCTACCAACTGCACAAGGGCACCACAGCTTGACATCCATCAGCATGTTTTTTCGACTATTCGGCCGGCACCAAGTTGACACCGCCGACTGACGCGTGGTCAGCCGATCAGAGGCACCAAAACGGGGTCGCATGCCTTAGACGAATAAGGGTGCCATCGATGTTGGGTATTATTACCGAAACATTCGGATTAATAGTTGAAATAAACCTCCTATTCCAGAGTACTTACCCTAGACCTCAAATAAGACCTGCGAGTGGATGGTCTTAACAATCGGGTGGTCGTGGTCCCGGTTTGGGATAGCGAAGGATAGGGCAAGAGGACGTCCAAGTCCAGTAAACTCCAAACAGCACGCTCACTCTAACAGGGCGGTGATAATGGGGTAGTTAGACGAGCACTCATCGAGCAGTACTTGCAACTGTCTTTCTCCAAGCGACGCTTGTCCCAATGGCATCCGTAGACGACGATGTGTCGGTCCGCCGTCAGGGGAATTATTCGTATGATGCCTCGAGTCGGTCTCGGGAACTTTTCTCGGTTTCCGGTTCCTAGGGTTGCATCCCTAGGTCCAATAATCATCTGTCGTGAAGGGGCGAGTCCTTCGGGGAGATGCTAATTTCTATTGGCCCCAACCAATTTTATGAAGTGTCGGGCGGCGATGTAGTAAAATTTATTTCTATACCATGAAGAGTGCTCAAAGACTGATCCAGGTTCTGTCAAGCTTTTTCTACTATCTATGAGACCCTAGCCCACTATGCACTGGATACGATAACGATGCTAAGGACTACGATGATGCGTGCGGGTATTTACGCTTTGTTGGTTACCATAACACCCACAACGGATCTCTTATGGTTCTTTGATACTTTAAGATCCTTACAATATATCAGACATGTCTACAAGCCCATTCGGTGAATTCTTTTCTCTCTGAAGAGGGTTTTGGCGTTCAACCGGGTATGCTGAAAAGCGACTAAAGTTAGCGCGAGAAACATTATAACACAAGCTCGCTGTCTTAGCAGGTCGGGCTATGCCCAGGAGGGGAACGATGATGGACACGTGTACTTGTGCGACCGGTCATGGACATATCTCTCCGTTGGAGCGTCCGTTCCCAAATGGAGAGAGACTGTGACAGTTATCTACAACTGCCGGTAGCCGTGCCCACTCCTACGGTACCGCTAGTCACAGGGATAGCAGGAAGTTAGTCCCAGTTAGCCATCACGCGGAAGTTATTGACCGTCTGAGTTATTGTTCCCATTATGAGCCTAGCTGAGATGAGTCTCAGCGCGGCTCCGCCTGTTGATTAAAATGTTTCCAGATTAGGTACTTCCATGAACTGATTTGCTCATACATTGACGGCGGGCGAGATGACTACGCTTGCCGACTACGTGGGCTCGGCTCACAAGCTGCGCGGAGTGATCGAAATCAAGTCAGTTGCACATAGCCTCACCCAGCACCCTTGACCGGAGCAAAAGTGCTGAATGACTGCCCGCGCAACAGCTCATGTCTAACTATAGGTCCAAGGAGACAACTTGGAGAACGTTCCTGCGCAATGCTCCCAAGGTAGCCATGTGCCAGGTAAACGCCTGCTAATCTAGTTAAGGTTACACACTAGAGGGGTCCCATTATTGCTCACGTGGGCCACGTGCTACACTTCGCCCATAGCGTACGGTCTTTCACTAGTTCCGGGTACCCACATTACGTACGTTCGTTCACTACTCGCTCAGTAGCTAAGATCGGGCTCTGGGGAGTTCCAATAGAGCCAGGTCCGAGCCATCAATTGTCTGACATATTTTAACTCTAGAACTAAAGCAGCCCAGGTGGGAAGGCCACAAAGGAGCAGCCGGAGACTATCAGATAAATACATACGCACCACTAGTCGTCATAAATAAAGGAGTTGTCCCCATGCTACTTAGGATTCAACGGCTGGTAACGGGACGACAAATAGGATTACGGTTCTGTCTTAGTAAGGCTTATTCTATGGAATGGGGACGTTGGGCCTTCAAGAACGTAAGGGAATGTCAAGTCCGGCTTGGTTTTTTCCTGATAGGCGTGATACGCGAGCTTTTGAGTGTAATAGCGGGAGTGTCTGTTGTTAGATTACTTTTTCCGTAGTATCTCACTCAAACTAAATTAACACCAGTAGGTATTATACGCGGAATCTTCCGCTTTTGACGTAGAGCATCCCGTGTCCAAACCGAATTGTCCTTTTTGGATCGCATGACATAAGGTTAAGAATTTACCACCACTCGTAGGGAAAGACCAAAGCGGGACAGACAACTGCCAGCGGGGCATAGCCTACTTCCTGTTATATCAAGCTCCAGCTGACTCAGAACCAGAGTCAGTAACGCCTATCTCTGACCTTTGGGTACTCCCACGCGGTATCATTGGCGACCAGCTTGTGGAGGATCCATTTAGCCACTCAACTTGTTTCTAGTAGAATTGAATAGACACTGGAGAGATGGCCAGCGACTGATCTTGTCATACACTTGTAGGTACTGTACCTAAGGTGGTTCAATCCTGGCTACGGGTAACAGTTGGTGAGGTGGGCCCTTCCTTGCGTTTGATGGGGGCAGCCTCGTTGGGACCGACTACCTAACCAGGTATGGTTTCCTCGCAAAGCATGGGCCGCCAGTATCAACTTGAATTCCCGGATTACGTAGCAGATTACTCCTGTAGTTCTTACACGCCCTCCTCTAGAGAGGAGCCGCCACATAGGGTACGCTCGTCCTGGGGATATTCACTATACGACTGTGTACTCCCTGGCACTGCGCAATAACCGGAAATAGGAACATGATAGCAAATCACAGGCATTGACCCCAGTGAACAATACCAACCTCAGAAAATGGGGGAACACCCTGCACCTCCGTGCTGCCTATAATACCTCATATCGTCGGCTCTCCATATGAGGGATAAAGATTCTTGTGCTTCGAATTTCAGACAGTCGACCAGTAGAGCAGAATAATAATCGTCGACCTGGTCAGTAAGGGGGCCGGCTAACGTAGACGTTCCCTCACGACCGCTCAACGTGTCTAGACAAGCACACAGCATATTCCGTCCGGATCCACCAGTGTATATTGGTAAGTTGCTCCCAACTGGTCAGGATGATCCTCGAAATTATTTTGGATAAATAGATACAATGCCTATCCACCCAGGTAACACCACTGGTACGCTATTTAACGCCTTCTCCCGGGTCGCTTAACTAAGTATGCTACACCCACATGCTTCAAATATGGTCGTTTCACCCTGTCGGTAGACTCGTCAGACCTTGTCTCATACCCAGTGATTTCAACCGACCAGTGGTGATATAGTAGACCCTGGCGGTAACGATGTATCCTTATTGACTCACCTCAACCCCCTGTTCACACACATTACGCCCCGTCCGGGGCGAGTAGTGCTGCCAGGATTTTGGGGATACAAAAGGTCTCTTCCTTAGCGGTGTAGGGGCGGATTTACCTGTTTCTCAGGTTAGAGTCACATAAGCTCTGAGATAGATATGAGGGCGTCATAGGTTCGCACCGGACATACCTCGCATGTCCCCCTGGCGTAGCCACAAGGTGACTAGAGCCCACCCTGTCCGCGACCTTATGGCCCACATCTCGCTACTCACACCATTGATGTAATAGGGGAGTTATCCTTCGTTCAAGTCCGTTACCAGGTTCATCAAACAAGCTTTACGGATTGAAGCATCCCGGTAAAGACAGTAGCATGACTCCAAGGGCATTTTATAGCCTTAAAGGGCGTCCATGCGGGCCGGCAAGCCACTAAACCTTCATCTCGGACTGTTGGTCCTCTTTGCAAATTCATGAATGCTTTATGCTGGGAGACTAAGAACTTTTGAGGTTTCTATAGTTCAGCGGTGCGACGAAGTGGTCAGGCGCTGTAAATGAATGGAATACTCCTAGCGGGTTACCCCAGGCTTGAGGTTTTCCTAATAAACCCACAGCGTGGATCTCACCCAAGGCGCTAAGCCATAAATCAAGTCCCTAAATGTCCTTTTTAGAGCAAATGATCAGATCTCTGCGCGAAATTTGATCAATGTAGGACCGCAAAACCGCGAAGTCCCGCTGCAATCAAAAGGCGTTATACCGCCACCATTCCCGTGTGCAAATATATAGGCGACACCGCTGCAAAGCTCGGCTCATGCGATCATAACCCCACGCATAGCTTCCTCAATGTTATTTGCACTTCCCCCATCACACTGATATGCCCGGATGAACACCATTCGGGGTTTAATAGCCAGAAGATCCGCCTGCCTAAGATAGATTGTGGTTTCACCGAAGTAATGCCAAGCCAGTAGGTGACAAGACTGTTATCCATTCACGGGTGTAATATTTGGCGGTTCTCCTACAGGGTCGTTCCATGTGCAATGGGCCCTCTTACGACCCCGAGCAGCCTGAAGTCTGTCGAATTAATCTTATTCCTCAGCCCGCGGTCAGGAGGGCCGTAGGTCATACAATCAAGTGAACTCTGGCAGCGTGACGGCAGAAATGCGTAAGAACAGGGCTGTAACGATCCATGCCGGGTCAAGAGAAGGCAAACGGGGCTCTAACGTCCGATCTCGACGAAAATCGGAGGAACCGTCGCTAAATCGCTGTGCGCATTATTTACTCGGCTCTCTCTTGCCCATAAGTTTCTAGGTACGTACGCACCAATAGACAGGGGTATGTACTTTCGGGTAAGCACTGATCGTGGTGTTGTCAATCGGCTTCACTAGTGCTAGTGCTGAGAGTTCACTGTCCTTCTTCCGTGCTAGTTAATGAACCGCTTTCTATCCGGAGCGGTCTTCTTTCGCTCACTTGTAACATGCGCTAGTGGCACTACCGACAAGCAAAGCTAAGGTGCCTCCTCATCGACCGGAGGTCCCTCCGAGTTTAGACGAGCTTTGTTCACTCAAAACGAACACGCTGCGCATAGAGCAGGAATCAGTAAAGGGAACAACCTAACTGCAAACACGTGGCGGCTTGTCGTGTCTGACTACCGGGCAGTTCGGGTCCTAGGCGGTTAGTGAGCGGAACGCGTCGCCGGGCGTATCCGTAAGGATTGAAATAATTCTCTAAACGCCCCGCGTCGAATCTATGTCCCTTAGGCTGTGCCCGTCATTTCCGAAGCGCCCACAGGTAAGAAAAGATGGGTTTTGCAAGGCAAGGTTGCCGATTGGCGTTCGCAGCTGTTTAACAGCACATGCCGCGTGCTATACGGCAAGGAGAGCCTCTACTCATGACCGTCATCACACGCCATATGCCGTGAACCCCCCCGAGGAGTAAAGCGATGTTCTGCTGTACTTACTTCACAATTGTTAGCCGTGGAATTCGCATTCATTCCAACCGTTTCAATGATTCGAGCAGGCGAGGCTCCTGGGTGTTTCGTAGCAGGGCCCAACCACGAACATCTCCTTAAGCATCCACCCACGTGTAGTATGCACACCATAGATGGCATATGATTGTTCGAATGCTACCGTGATGCGCCTGTCTGACCAAATACCCTGAAGTTGCGGGCGCTTGTCCAAAATATGTAGGCGGGACACAGGGCCAACGTATTCCCTACGTCCGTGTACCTAGCTCAGGGCAAGTTTCTTCAGATTCCATTGGGACCCTGTAATAAGCAGCTTTTAAATTACGCTCCCTTCAACGAGACGGAAGCGATTCCGAAGCACCGAACCCTCAGAAATGGACATAGCTGGTGTTGTGGTGAAGCCTGAAATCCGACTCGGTACTATTTGTCATGGGGCTCCGGATATTTGTTGATCTTCGCTGCATTTGCGTCAAACTACGACACAAGTAGGATGGGCGTACCGCGAATTCATGACATGCGCCCCGACTATCATGAGCCAGAATGTAGAATCCAGGCAGTACCATTGGGAATGATTCCGTTGATTTGCAGACGGCGCATTCACTCTAAAGACACATATTGCAAGATTAACCTTCACTTTAACTCATGTCTCATACGGGTTGTACCAGCTGCTAACAACTTGACGTGGATGGCCGGGAAAAGACAGTAGTGGGTAAGAGGCATCTATCAGCGATACCACTTTGAATATGAATTATCCTATTAGAACCGTTCGCGTCGGCTTCTTAAAGTTAAAGGTCAAGAAGCGCCGGCCATCGTTAGGGCACATAGTGGCTATGAGTTGCGAACGTCATAAAACTCGTATTTAGCGAGGTCTCGGGACAGGATAGGGTTGCTGCGTAATTGTACGCGGCAGACAGTACAAACGTGCGCGCGGCGACTCCTATCTCTCCCGCTTAAGCTTTATATCAGCCTGCGCCGGGTGTGCGCGCGAAGCGAGTCTGAGTCCCGGTCGCTAGTGATAAGAAGGCACGTGCTCCCGAATTGCCCCCCTCTAAGGTGTGGTCCTGACGAGACTTTGGATCACGCCTCTGCACAACCAGGGGTTAGCAAGAAAAGCCCAACCTCCTTGACGGCCGTTCGCCCAATTGTAATGTCCGATATTAGGCGAGCTCAAAGTTATCGGGTGCTAAAGCTTCCACTTATCTTTAGAGGGCGCACAGTTGAGGTACGGGCCCGAGAATCGGTTCTGCCACGTAGACTCTTATGTGGTGTCGTATGTGGCGTAGTTCAACCGCGTCACGACGAATCGTCATAAAGGGTAAACTATCCCTAAGGGTTTTGGAATCTTGCGCAATAGTCGCCTTTGAACGGAAGAAGCCTTACCCCTCTGCGTTCACAGGGTAGCACAAGCTGCGACGAGAGTTACTGGTTGTTTGAGGGGTGCCCTAGTAGGACCTCCGCCGTATTATGTACTATCATCCGAGTGGGCCACCGCGCCCGCCTTAAACACATGCTACCAGTCTGTGCGAGTTGCAGGTGGATCGGCAAGGGGGGGTCCGCTACGCATGTAACCATAGGGGAGGGGTAGCAAAGGTGCGAGGACCACATGCCGGCGTAAAAACGAACTCTCACATGTCAGGCTTTGCATTCTGCGCCCCATAATCATCTAGGCTTTGCCCCACCGTAGCGAAACAGTTAATGCTTTGTCGCTCGTGGCTTAACTTCCTACGCGTTCTAGTTGCTACCCGAAGCGGCGTGTGGAGTCTGCGTTTTTAAGACCGGTGTAGTTCGCATGCAGACGTGAGACCCGAGTTGTGCTTGTGCCTTGTGGTACAACTCCACATATAGTCGCAGTGCGCACGCAAGGCGCACTTCGTCGCTGGCCGGGTCGGGTCGTACGTGCGTTACGAAGCAAAGAGTTGTTTATTAGAACGCTGTGATCCGCACGTAAGACCCGTTACTAGCTGCTCCTCTGTTCTTGCAAGGAGTGGTCAGCACGTATACCAGAACAATATCCTGTTAGAACTGTTAGACATACGACACTTCTCCACCTGGGATACGTAGGAAGGTGCCCCCTCACAACTGATGTCTTCCGCATCGCAAGACAACGTTGCAAAATATTACCCAGCGCCGCGCGTAGTGTGCACGTGCTGGTCCCTCGCAGTACCGACGGTAGATTTAACTCCTAAGTCGTTAAAAAAATTGTGATTCTACGAGGAGAGGCCTACGGGTTCTTTCACCAATTCGATAACTTTCCGACCGTCATATTCCCAATGAATGGAATTGAACTGGACAACATATTACTGACATAGAATCATGCGAGTGATCAAGAGTTCAGGAGTAACAGGTGATAACCTCGGTCGTGGGCCCGCGATTAAACAGACCTTAATGCACTGGATCAACGTTATAACTTCTCTGTAATTGGACATATCTTGTATCCTACCCAGACACTGAGGCACGCGGCTGGCAAGCCCCCAGGACAAGTTCATGCTGCGATGGGCTTTATTCGGACTGCCGGGCCTGACCAAGGCCGATCTATGAGTAGGGCGCGGTAAGAGCGAGCCCCGTTGTCCCAGCCGTGCTGAGGGCCATCTGCCTGGTAAGATACACAAGAAATACGCCTAAATGTTCGAAGAAGGCCTTAGATGATGAAACGTTCTAAACATGCGCGCTAACAGGCCACACTGTATGACATTGCCAGTCTCAATGGGGGATACACTTGAATTAGCCAATGTCTTGCCTCGCCTGACACCACTCGACTTCGCTGCACGGAGCAGCGCTTTTCCTTCAGTAAGCCTATAAGGGGATCTCTCTAGTCACGAACTGCGGTTTAACCCGAGAAGACGTTCCTAGTGAGAGCGCGAGCTCCGAGTACGTTCGGCTAGACTCCGTGAATGGGAGACTTAGGAACTAAGCAGCGCGGGGTTTCGTTTATTGGTACTTGTGCTTGAGCGGACGGGAGCACTTCCTGAGGCACATGCCGGGCGGGGTCGCAGGTAGGCTTAGCAGAGACCAGTAGCTCGTCCGCCTTTCCTCCCGAGCGTGAAAGCGGTAGCCATACACGGGGCTAATAGGGAGCGCACCATGCCCACAGTAGGCCAGCCCGGGCCTCACTCCCCCCATTTTCAGGCTACCTGCAGAGCCATTCGGGTTCCGTGGCGTTTCAGAGAGACCTGACTATCGGTTTGTGTCAGCCGATAGTCTTGCGATGTAACACACGAAGGGATAAAAAAGCGGCCGCAGTGTAGTACCAGAGGTATTTAAACGTTAGACCGAAATTGAGTTTTCGAGCCTATCGAATAATTTCGCTAGGGCTAGGTGATCCATTGGTTGAATTTGCACGCTTGCAAATACAGGCAGTGTGTCATCCAGCTCGCCATAAATGTTCAGGCGACTGACAAGAATTCGAAACTCACACGCACTAGTATTAAGCTTGGGTCACCCTGAGGCACGGGCGATTGTTCCGGGATTGATATCGGACGCCGCTTTTTAAACGATGTACAATTATCATATTTAGCCCATAGGCTCGATCATTCAGCCTTATGCGAACCTCGAAGGCAGGCGGAGTTAGTCGCAGTCCTCAAGGTGCCTCGTAACAAATAATGGGCAGCGCCTGACAAGGGTTGATGTACACTCTCACAACACTCTTAATTCAAAGGAGCCCGCTTATGGATAAAACTAATCCCAGCATTATCTCTCTAGGCTTTTTTTGGGAAGCTTAATCTCACACCTTAATTCCTCGTTCGCGGCCCCGTTGACAAACCTCGACGCCCAGCCTTATAGGAACATTAGATACTCGAAATATGGCAGCGAGAAAGTCCGAAGTGGCTACAAAATGACAATTGTCTACATCGGGAGTATTGCCTCGGTCTTTGGTTGATTGGAACGGGGTTGCATAAAGTACGCGTACATATCGTTGCCGGATAGATAATCTCAGTATTATTCTATTTCATGTGTGTGTAACGGCTACTCCGAAGTCCTGTCAATCAAGACGGGGGCAAGCACAACAGTTCACTCACGGATAGCAGATTATTTACGGCTGAGTTCAATATCGGCAGGAGGAATTAATTTGAACGAAAATACACGCCCCCGGGCTACTGTTTAGCAAGACTATCATACGCAAATACTATGCCATTGCTCGGTGGAATTTCGTTTCCGGACCATGATAAACCGTGTTGTTATTCCAAAAGCGAAAATTTTGATTTAGATCGGACCCTAGCATCCAATGCAGGATCTAAAATAATAATGCGGATAAAATGATAAATTCCCTGCGATCGACGGACGCTAAGTATTGAAGAGCATATAAGAATTGAACGGGTGGCTCCTTCGGTTATGTGGCACTGTTTGCTTGCCTGGCAGAGTATATCAACAGTGATCAACGCGGGAAACTCGGCCGCGGTCCGATGCTGTCTGCTTGGTTACCTCCGGTTTACCATCTGGTTCTACGTCCACTTCGTGCATTTTTGTTGGGTAGGCGCACCTGATGAATTGAGCTGCCCCCGATTTCGCACGTCTGACATCCGAATTTTTTGTCTCAACTTGTCAATTCCGGATCGTCCTAGCTCAGAACCCACGGATCAGCTCGGATAATTTGTTTGGTTGTTTTTACACGTTTATCATACGAGCACAATGGATGGGGCTCATACCCCGGCCCTGCCGGCGTGTGACGAGTGGAGATATTCCTTCTCTAGCTGTTCCTTGTGTAGGAGCACGCTTGGTCCTAACCGTAGCCACTTCGCGATATTGAATGGTTATGTTGCAGCTACAACCAGAACTGGTTGAGGGAGCCCCGAGCCTCGATCGTCTTCACGTCCATACGCATTCGCCACCCTAGCTGGGCTTAGACGTTAAACTGCGACCGGGTAATTACCTAATTCAGTCAAGCGTCCCGTTCCACATTAATATTCCAGATTTGCTTAATGGCCCAGTTAAATCTATCATTACGTAATAGCTGTTACTCCCTAAAGCGCCAAACTTTTGACCCCTTGTTACTTACAAATAAACGGGTTGCGTCTTTCTTTCCACGGACCTCCATGCTCGAATATTGTCTCTTTCCGTATTGTACTGTACAACTCGGTGACAGTTCGTAACTACCTTCAATAGCAACCAACCCCTGTTACACCCGTCGGGCTACTAGTTTCTCTTTACAGCCAGCGTCTGCAGGTAGCTCAGCCCTCAGATTCAGACACAATATGAGGCTCAACTTTGCACTGAGTCCGTGGCCGGAGGGCTCTGGCTAACGGTTACGTTAGCATGAAGTACTGGCTTCATAGAGCCGGGCCTAGTCACACTGGTTGGACACTACCCGGATAGAACGCAAGTTATAAGATATAGGGCAGGTTCTGGGGTGTGCCTGGATATTTTTTGTCCCAGGTTCCTTGCGGCATTGCGTTCAAGGTCTCTCTTACCCAGTCGTCATATACAAGATAATACTATCGACAATCTTGACAACGTCTGTTGAGAGCTCGCGTCATAGGGACGGCAGCGCTAGGGAGGTATGCCCAACCGGGAATGTGGGGTTCTCCACACCGTATGTCCGATGGGCACAACTAGACCGTGTCATTATAAGAAGCTACAACCGAGATGCCGCACCTCTTTAATGTTGATCCTGTATTGTGAACTATCACTCAGCTAATTCGGGGCCATAGGATATAGGCTTCTAAGTCGACTTTTCCGATGAAAGATCACTATCCAGCGTGTCAAGGGTAAATGACATCAGGACGCTGACAATTTGGCTGAATCCTTGGCGACGCGGCAAGAATAAAGGCATAGCACGGGCGTTTGAGGGGACGCTGATTGGCTCGGGTCCAGGTCTGACCTCCACGGAGTCCGGATTCGAACTCGGTCAGTCACACGGGAGGCTTAGGAGCCTTCGAACGGACGATAATATCCCGTTACTCGCCACTGTGCCTGCCTATAATGGAAAAGACAACTTTTTGGAAGGAGCTCGCATTGTCCGCGGCCGAGCGATTTCATGTGGCTTTGTGAAAGAACTCGAGTTGGACATAATGTCTGTATATGTATCGCCGACGCGACATATCCTGTACGTGTTGTCGATGATATGAAATTGACCTACTTACATGATACCAAAAGGAGGCGGCCCCCGGAAGGTTGGCCCGAAACACGAGCTCCTCGCAAATGATGTCATGACGATGGCAGAAGCCGAGCTCACGTCTCATTCGGTCGCAAATCCTTGATTCGTGCCGTAAGGAACTTGGGAGGGTAATAGCAGGTGCCACGTTCTCCTATTGTCGGACGCAGTGCTTATGTAACTGATTCCCTGAAACGTAAGCTATTTCGTCCGGAGATAGAACATTATGTCCACAAGGCAAGATATGTTTCCTATGAGAAGAAAACGACGCTTAATGACTTGGTGTTCTTTCTCCAGGCAAGATACGCGAGCGCCTACGGAACAAATGACGTCGTCTACGACGTCCAGATCCCAGCTTTTCGTTCGCTGCGGCCCCCAACTTTGCCAGTAGTGCCGATTGTGCGTTGCGGCAGGGGTCCTTCATACTAGTGCTTCATGCATTTGCCAGGTACCATGGATCTGCACTACTATCAACCGGGGACCGCGCCATCGCTTATGGGGTAGATGATCGCGCCACATCGTTAAGCGCGGATTATCGGAAGCAATCGTCCCACGTATCCTAGGTATAAGATATAAGTTGCAACCGCCACTAATCCCTCACACTTTCCACGGTGGAATCAGATGTCAAGCACTACAAACTTGGTCCACAGATGGGCAAATATATGTGCTCATCTCATAAAAGGTGTGACCGCTCGTTCCGGAACCTCAACTTTTGCTCGTAGCGGGTATTCCTGACGCGATTCACCAATCGGGGCCAACGGCTGACTTAGACCCGGCAAATAACACAGTCCAGCGTAGCTTGCGCATTTACGGCTTTTTGAGCTGGCGTTCCCGCCAGATTTGCACAATAACATCGATGAACCTGTGCTGCGGCTAAATGATAACGGAATGGACAGTTCGCAGTGCTTCTGATTGAGTTCGTGACCAAAGTCATCCGTAGGCAGGGCACTCTATACCTCACGTATGTAGCCTGTGTATCCTTGCCCAAAGGCGCGCGCAGCTCGAGGAGGCGGGATTGACCGGGACACATGTATTCGCCTCCGAGCGAACGCAGTAAATATTCATACGCAACGAAAGAGCTTCTTACGGTATTAACAATTTCATCCGGGGGTTATCGAGGATCCGCGCCACGGGTCTGCGCGAGACTCACGTGGCGGCGGATGAACCCGGCAACAGTCGGTGCCCCTGCTCAGCAGAGCGTTATTGCGAAGTCCATGAAAACCTTATTCACTAACCCGGAACAGCCCCTTTAATACCAAGTGTGAGTAGAATATTCACGCATGGGCAGGGTGTGGCGAAGAGGCGGCCACACATCGACCGGAAATCTCTGTCCTGCGTTCCATACCCCGACGAATTTCATTTCCCCACGGACTAACTTTCAGGGGGAATAAGCGAGGTACCCCTGGCAGAAAAGGCGCAATGTCTGATGAAATTTCTCGTGATGCTCGTGTGGACGATGGCAAAGCTCATGGAATTAGCTAGCAGCAGTGAAGTAAAAGCCGCTTCGGCGGCGACGGAGTGTATCACATCGGGTCGGATGTGGTCGCGGAGTGACGAGATCGAGGATGTGAGAGATAAGGCCCGTAGATCGGCAGGTGTGTGCCCTACGGCTCACTCGTGGTCAGCCAACTGAACTCGTGACCCTCGTTATGGATCTTAAGCTCTAGTAGGACAGCCCAACTACCACGTCTTAGAAGCCAACGATAAGCCCATAGGGCAATGTTTTTAAAGGAGCCCCCGTTCGTTTCGGCCACAATTAAGAATTGAGTTGATCATGAGGACTATGTGATTTAAAAAGTACACGAAAGGCGCTCAACGGAGTGTACTAGGCATTAATCATCCGAGTACATGCTATAGCTTGTCCAACACTGTGCGATGCGGCGAGCGCGGGTCTGAAACGCACCCGATATTGGTTATGTGTTGGGGTGCCCATCGCGCTGTGTCCCCGGTGGGAAAGTGATGTGCCATCATACAAACGATCGTAAATCTGCTGATAAGGACAGACGGAAGGCTAAAATGGAAAGATTGAGAATTGGGCGACTTTCTTTATTCTCAGAAGCAGGAATAGTCATCCGTAGTGCCGTCAGTTAGTAACAAATAGTTGCACGCTGCGGGGAAATCCCCCCACTCCCGGAGTACCCAGCAAGTTAGGAGGGTGAATCCCGGTTGGGCTCAGCGGACACATGGTGCCGACCAGTATTTCCGCATTTTACGGGACCCATACAACGCGTAACGCTTGACACTGGAAACAATAATAGATGTGTCATGAACTTCTAAAGGTCAGTTCTGTCGTCGATCAGTGCTCTCCGCGATACCCGAATGCGATTCTAAGAGTGCAGCTTTCCCTAATTTGCTACGCGACGTATAAATTGGCCTAGATTGATGGGTGGCGTAATGAAAAGTTATGCTGTTGGTTCGTATCCTGTGTATTTCGGTTCTTCAATTCGCACAGTGATTAACGGCCCATGACTGATGGACGTGGGCGTGTAGTATGGGTATACCCCCCTCAATCACCCCGAGTGCACCTTCGTGCGAGAAGCACATCGCCTACATGATTGGGTACCCCCTAGCTAATGACACCTCCGGCCGGTGCGGCGGAGTCGTAGAATGGGCCAATGATTCATCCCCTTGTTTCGTCAGTTCAGGTCCTGTGATGCACCGTACCTGCCTTATCATTCTCGAAGCCTGTTTAAGTTTCGTTTGCGAATTCTGCGGCCTGCTCTGATCCGGGGAGACCTTCGAACATGTGGTACCGAGACTGAGGTGAGTAGTTCAACCATTTAACTGGAACAGCTAAATGTCGCTTTCGCCCCTTACTTCTTGTATCTTTCGTGGCGTTACCATGAGGAGGGCATTTCTGACTGTCGCTTGGATGGAGGAGTAGAATAACCAGTACCCTATTCTGGCCCTGTCAGCGGCACCGGAAACCGGGCCGCACGTGTGTTCGCAGTCATTTGTTGACGAAGCATGCGTCCAGTGAAACGTATCAGGCATAACTTGCAGGGTAGGAAAATAGGCACTCGTAGCCTAGGTGCAAGGCGTTTTATGGCGCTAGAACTTAGAAACGAAAGATCCGGAGCTGTCCGATAACTAGTTTAAAGAATCACCATCGGGGGATTGCCAAACGATACTACCATTCCTTACACCAGTGAGGGGGCGCTTAGTGGGCATGGAGTTGACGCGGGATGCGCGGGCCAACAGATTCCAAAAAGTGACGCTATTTAAAGAGGTGGGCTATGGAATCGGCATGCTTACAGCTGCTCTTCCTCCTGTAGTAAGTATATGCGACCGATGGAGGTCAAAAGGTCTTGATTCGTCGGTGGCCGATGTTATGCGGTGAGATACCTCCCAACGGCGTTGATAAAGGAGGAGGCTTACCATTACGCCCATGTTCGAGCCCCCAGCCAGACATCGGTACCAAGAAGGGTAGTTGGATACACCCCGTTGCCACCAACGAGTGTCTTGTGATTGGCCGATTTCACCAAGGGCAGATCGACCTGGCGTGGAATTCCCTTATGCAACAGAGTCGACAGTTTGGGGTGTAACAATTGTGCGTAGGCCCAGCCGTCGAGTGGTCCAGGGCTGGTACTATACAGCTAGCCGTACAGAATACTCGAACATTGATCACCATGTGACACATCCGAATAAAGGCTAGCTACTTCCGCACAAGCAGATATATTGCCCCGAGTGGATTCCCTGGGGTCTCTGAGGTATGGGGATAACATACTTTTTAGGACTACAGATAAAAGTCTTACATGGAAACCAGCTACGCGTGGTAAACGGATAACGCCACCGGATGTTAATTGGCCTCGCGAGAAGTTTCATATGCACTTAGGGGTCTTAAGCCGTAGCGCTCGGTTTATGCGGCATTGCGAAGTCTGACGAGGCCATTCGACAAGTCCAACAACTTATCACACTTGGTTTGTGCTGGGCTGTGAAGTCTGCAATTGCAGGTAACTTAGCACTCCGTGATCTACACCCAACCGGCCGTACCTCTTGGGTAAAGAGACTGACCCGGGTGTGATATCTGTGGTAGCCAGGTGTTCATTCAAATAAAAATTGTCCTAGCATTCCGACTCTAATTTTCAAACCGTTGCAAAATTCATCGTTCTAAAAGCAATAGCTTGAGAGGTCCTTTTTTACGGGTCACTGCATCAATATTCTTTCCTCTACCACTCAGTTGATCTTAGTCACGGGTATAAAATATCCCTACTGTACTGTTTGCCGGGCGCGACGGTATATTACCCGTGGGGCGGCGCCATCCGATAGACTCGTATATATCAATCACTTCCGCGGAAATTTTCAGCGTGAGCCAATCGATTGACACAGAGTCCGGCACCGGGGTGACGCATTGAGGTCCATGACACTCGAAACTTGGGCTACGACAGGCGCGGGACGGCCGGCTCGTTACTGAACTGTCAATGGGGATCGCGTGCTTACGGTGCGCGAAGGATTTATTTGAACGAAGGCATCTTCTTAATTGTCTTCATTAAAATGGCCTGGTATATAGTTCGCTAGGCGTTTCTACAGTACGGGTAACTTTCTCTCAAGCAGGAACCGCAAACGTCGATGCTGCAGTGGCATTACGGGGTGATCTTAACATCAAGGAATATCTCCGGTGATTCGACACGTCTCCCCACTTAGCGCGTGACCTCTGACAGGTACCGACTGTAAAAGATCTACGTGTTATATTCAACATTATCCAGCAAGTCGTGGAGTGCGTACATGTTATTGTTTGTGTACTAGAACACTACTATGACGGGTGGAGCCATCATGGTTGACACGGAAGGATAAGGATTGCGCACCCATCAGGAACATGTACTAGACACTGCGCGTTACCACCATAAGCCAGTGCCAAGGATATTGGAACGCTAGGCTTACAGTAAGGCCACAAAGATGAGACTCCTAGATCGTCTGCCGTAATATAACAACTGTACTGCTACAACGACCGATATGCGCATGGCATGGATGCGTAGTTTTCAGGGCATTCGGTATACCGGAGCTGTGCCGAAATCACCGTTTCGGCCACGACGCTCACACGATGGTCTGTGAGACAGGGGGGCTCGCAATCTTCCCCATGAACATGGCGTGATTCAAGAGGAAGCGGTGGCGTGTTCGTAGGCGGGGCGCTTTTCATTTCACGAGAGTAAGACAATAGCAAAGTGACGGCCACGATAAGGGAACTAGAGAAACGAAATTATATTACACGTGCAGTCCGGATGGCCTTGCTGATGTAGCTACATGTCCCACTATTCGCGTTGCTACAGGGGGTCTAGGCGTCTGTCGGAGATTCTATTCAGAACATATGTACAACAATCGGCTAGGACCCACTGGCTAAACGCCTGTGGCAGAGTCTCGCTTTCTGTCAAGTCTACACTAGTAATAATGGTCGCGACTGTGTGCTTAAGCGATCCCGGGCGTATCCGATATGAGAGGTAAAGGTATATTGCTCGTCCCGCCCCCATCTAGGTGCGCGTTTTTCTAGATGATTCAGACCCTCTAAGCACCGACGATACTAGTACAAGAACTCTCCATGGTACCCTCATGCAGCTGTGACGTACCGTGTAAGTATCACTGTATAACTACGATTGGGTAATGCTCGTGTACCTGGTCTATAGTTTACGTATGGCACGTGCCAACCGCGCACCTTTTAGGATTCGAAAAGGCTGCGATCGCGGATGTGCTGGCTCGCTTCACAAAGAATAGGGCGCCGTATTAGCTCGCGGCCGGGTTGCGTTCCCGCTAAGTTACTCTATGCACGCTGGTATAAACTCTAGAGATATAAAATCATGAGCCCAGGGCGGGTTGTAAATATCAGCAACGTAACAATTGTGTGCGTTCCTTGGTATCTGCGCAATCGCGATTCTGGGTTACCGCGAGAGCCCCAGGTTCCGGTTTTACAAGTACAGGGCACAAGAGAGATACAGATGAGTGCACGCAAGATGCATTATCGCCATAACTGAAATGGAAGTTCCTTCCGCTAAAGTTGTACCGCACCGAGAGAAACCATTACTCCAAGGACGCTACAACGGGCTCATCTTCCCGTCAGCGGGTATGCAGTATACTTTACGCGGCCGTCCAACATCCCAGTCTATACCTAACCTTAGACATCGTCTTACAACAGCCGGTATCCCTGTGACCGCCCTACGTACGTTGTGGGTGGAAATCAAAAGACTAAATCAATGGATTTCGATGTCGGAGTGACTTTACTCCATGTGAATAAGACCGGACGAACGCCAACTCGAATTGTACCCGGCTCTCCTTTATCGACAGATGCGTCAATACACAGCGAGATCTATGCCTCGAGCAAATCCGGACACTTGACGTCTGCGATCGTAGAAGGACGGTTTTGTTAATCGTACAAACTACCTCCAATATAGCCCCTCGTACTGTTGACAGCGATACGGTGCTATGGCACTAATCTTCACTGGCGTTTATGGGTATGACAGCTTGGATCATTTACCCCTGACCACTCTTACATACGGAAGACAAATTCCAACCAAGCGCTGGATCTTCGCCAGTGACACCAGAATAGTAACCGGGACCACACATTCCTCAGCTGAAGGAAAAGGTAGCAAGTCACTGGAAGGCCTGGGCACAGGAACGATTGCCAAAATTCTTAAACGAGGCACGAGTAGTGATCCTAAGGCACGGAAACAGCGCGTGGCCGATCTGTCGTGCACCTTGTGGTACTTTTCTGGACGAAGAGCAACGTGTATTAACTCTTAACGCTCTTCTGACATGGCTCACAACGCAACAACGTACCGTTTAAGACTCACGGACACCTAACGCTTCCAACCCCCAAGTATTCACGATGCTCCCTCCGTCGTATACCACTCGTTAACTTGATAGGCTTGCTGAAAACAGTGCTCAGGCCCGGTCGGTCGCCTGTGGTAGCTACCTTACTTTACAGCGAATCTAGCGATAAGTTACGTTCAAACAAGACTGACTTTAACGCCGACGGAGAGTTAACCAATGGACCTTCCAGCGGCGCTGACTGTTAGGTGTGCAACTCCCCATGCCAATTAAAACCAATGGGCCTTACAAAATATGATCTGAATGTCCACATTAGTCTGGGAAGAGTCATATTGTGTCCATAGACCAACTTATCAATAGCCCCAGATACTCCCTTGCGGTATGGAGCTAGCATAGTTGCTTTAGTTATTTGAGAACGTGAACTTCCTATTTGTTGTTTACAATTCTAATCGTCTCCTATGCGAACACATAGAGTCCTGACCTAATTCGTTACGTGGCTTGGAAGGTTGCACAGGTCTATAAAGCCGTAGACAGTGGTCCAGATCGTCTTTGCGTTAATTCGGGACAAATCCCTTCCAGTTAACGTTACCACACGGGAGCTCCTACACGAAAATGCTCTTGGGTGTCCTATAACCTGTACATCTACCCAGGCTCGTCGCACCCCCAGGGAAAGGCCACATCTGCGAGGGCTCTGGCGGACCGTGAGTCTTTATTCTTACTCCAACTCCCCCGAAGTAGGCACTGAAGGCCGTTCGTGTGACAGTTCGACCCAGCAGCTCCGCCGTAAAATGCTACAGAATGAGTGACCCCCCCAGTACGGACACAATAGATTGTCCCTCGTCCACCGATATGCGACGCAATTATGCTCGAGCACAGTTTGCATACGATGCCTACAGATGGGTACCACTTGGGCCGGGGCGACTTTCGCCGGGATTGCCGAATATACGTAATGCCGTCATCGGGCCATTTAAAACGGGGAGACTGGGTGGGGAACAGTGAACCCTGAGGCTAGGCGCAAACATTGAGGGGATCGGACCGTTCAAGCCACGAATCCCACGGCGAAGATATCTAGGAACATGTAATCTGACGGATCTCTTACGAAAATCAGAGAACTGGTGCATCAGTGTCATGCCTTTTTAGACATCATATACATGTCTTAGCACATGGCAATTGGGTGCACAACATCCTTGAGTCGAATTCCCTACCGGTTAAGGGGACGTACAGAACACAACATAGGAAGTCTAGTTCGATGACGATCGAAAGCTCGTGCAACATTTACATTTCACGACGGACTCATTAACGTTGCCCCGGCGTGATATACGTCTGCCACTCGGCCCGTCGTACTAAGGTAATCCACTTGAAAGAGCAAGGTCTCTTGCAGGTGACAACACGTGCCTTTTCCGGTACTCAGGTGAATATATCTCGTCCAATGGGCCTCGCCGCAACTATCACCCTCGTTATCGACGCTAGGACGGTTGGGGATTTCTGCATTGGCTCGTAACTACCATATAAACTTTGCAAACCGGATTCCTTGCGTAGGGACCTTCATTGATATGGAAAGCTGCTCATCGTAGGGTATTTGCGCCGCGCAGTTTAAATGTCTTAATGCTGCGCCTCTAACGCTGTCATAAAACGTTTTTGTGAATAATAGAGACTAACTTCCGCTATTTCAAGTGAGTCTTGCTGGTCAGAAACAG;LEFT_SVINSSEQ=ACCACACCCACACAACACACA GT 0/1 0/1 +20 850000 . A . PASS SVTYPE=INS;END=850000;SVINSSEQ=CCCCGTTTATGAACTCAGCGCCGAACAGAAAAAATAGCCCCACTTTAAGTCCGCTTTAGCGACTCTAGGGTCCGAACGCGCTGTTTCGTACATGGCACGTCGGTAGGCAAGAACTCCCGTCCTCAGATGAAGATGCGTAATATCCTTACGTATTTTGGAACTCAGGCTGCCGAGCATCTTATTGGGAGACTCTTACCACTTTGCCCGTAAGCAGGGAAACGACATTTGATAAAGGATGGCAGGGAAGCTTTTATGCCCCTTTTCCTACTACAACGTCGAATGTTGACTTCCTGGTTAGCGTTGTGGCCTTGTACTGACCCTACTAGGGTTTCAGCTGCCTAGAGGACATTCGACCGACCCACGACCGCAGCTCGCGGTTCATACACGAGAAGCTACAATCCGCTTAAGTATTTGTTCTTTTCGTTCTAGGGCCCGCGGCACCAAGGAGGCTTCAGAAAGAGAATAATTACTCGATCGTCCCGTAAGTAGTGTATCGCTAACAGGGCCTGCGTCGTCCATACTAAGGCAAGGTGCTCCAGCAGGGCATAGGAATTGACCGGCGGGTAACATTGGAGACAACATGTGATTTGTTGCTTAATCTCGGTTAACCCGCCCCGCTGTAAAGGCGAGACGGCAATCATGAATTCTAGCACGCACCCCGCCCGTCTCTGTCTTCAAAATGTATTTTTGGCAACGAAGGATCAGCCTGTCCCGAATCGACACTGTGTTCCTATGGCGTAAAGAATTCTGTTCCTGAATCGCGGGCGCACCGTAATTCTTACTTTCACATCGAATTGTTAGATGCTGACGAGCAGAGCGCAGTGCGGCCGGGCGGAGATTGCAGGGCTGGCAGAGCCATTGGCCGTTGATGGTGTTTAGACGCTAAGCTAACCCTATGCCTCATGGATACTTGCTACACAACAGTGTCTGCGTAGGCTGAAATGGGGACGGCATGAGACCTCAGTGTCAACACAATTTGATGCACTGGGTTTTCTGCAACTACTTTACTACGGCTTTGTCCTTAACGCGTTAAGGGACTCCATCTCATCCGTATCATAAACTCCGTAGTGTATTGGGGCCAAATCTAGAATACGTACCGTCGACAATGCTCACGAGGGTTACTCAAAACTCGGCGGGGTGCCTCAATCCGCGTGCCGTGAAATGCCCGTATTCACGACGACTAAGCACTTAAGTCTCGGGAGCTCTGTTGCGTCTCGTCTAAGGGCAGTCTTGCTTCCTGTGTCTGCAAGTTCCTCTCTAGTGTTTAGGGTGCCTAATATACTCCACGTGTGTCTATGGACTCCATATGGTAAGTAATGGTGTTTGATAAACCCCTGGCCCTTTAGGTTCTACCTAGCCTAACTTCTTCCTTTGACTTTTACCCCCATTGATCCATGTTCGTCGAAGTGGCCGATTGAGGCTGCCGCATGGCCAAACCGCTAACCCGATCGAGAAGGTTGCAAGGGCGCATCCGCAAATAAACCATGGTTGCTAATTGGGGTGCAGGCGTAGAATTTGTCGGTTCAAAAGGCCCTCGACCTGCACAATGACTTGCGCTCGTAACTTATGATAGGGCCGGCATGGGATTATTCGAGGGACTCCTCACACTCAGAAGTTTACTCCCGGAGCACGACTTTACGAGGTGTGTTGCTTTATGATGGCATATAAAAAAGATGCACCAATCACCAAAACCCAACTATCCTTGACACGATCAGTGCGCGACCTACGACTACTCTAGTGGTACGACTATCGCGATGGAGGGGATATTCGTATATTTGAAGTTCATGTATTGATTCGGTTATGGCGTCTCCCTTAGTGTTTATGGACTTCATGCGTGCCCCTTATCCGCCCGCAGGCACCAATCACATTGTGGAGTTAGTTGGAGCGAAATTGGGTGGCTGTACGGTCAAACTAGAAGCATACCTTCACAAGGGCGTGGCGCTATGGGAAGTGGACCTGAGGGACACGATGGGTGAGATTCGGACACTCTGTCTACAAAATTAGGAGGTACCTACTGCTAGCGAGCTTCAAAATTCGGGAAGAGATCCTCGTACCACGTATTAATGAAGAGCCAGTGGAGCGAAGAAATTATCGCAAGACCGACCCTGTGCCGGCAGATGGACGTGTTAAACATGGTACATTGAGCAGTCCGACTCGTTGTATAGTTACCACGTGTGAGAAGACTTAGCTCGCAGCTAGTGGACAAGAACTCGGCCGAAGTTTCGTTCCTGTATTGCGCGTGTCCAGGATGTGAACAGTCCAACTTCATTATTTTATTCTGACTTGACACTGGACGTAAGTCAGCTGCTCAGAAACCGGAGTTCCCTGCCTTGGCCTGGGGGCCCCATTTGCGGATGAGCCCACAGGTCTCGTAGACTTAGGTGACGCCGGGATCTGCTGGCCTTATGTCCCTAGAAGCTTGGATGACCGGCCCACGGCAATGCGTAGTCAGGGAGGTATCCATGACGTGCGTGAGTCGGGCGAAGAGGGCCCCACATGCACCTAGAATAGCTATGTGTGTTTCTCGGGCGGAGCCCGACGTCGTCCCGCTCATATCCAAGTGCTTTTTCCGGGGGTTAAGCGGTGGCTTGGGCACAAACGGTCGCCTCCGCCCGCTTGGTCTCTCAGGTATTTCCGGGGGCACTCATAAACTACGAACGCGATCTCCGATAGCCTTCAGTTGTGGGGATGCGGCTAAATCCAAGCAATTGCGACGCTTTGGGTGTGGTGGGGGTTACTGATCCGGACTGCAAATTACTAACTCCGTCACCTATCAACACGTCTCCCTAATCTGTTGGAACCTCGCTCTATGACATCAGAATGCGAGCGCGGACATGGGACATGTCGGGACAATCTATTCTGCCTCTCCGGTACTGGGTACGATAAGCGCGACACAAGATTGTGCTCTTACTTCGCCGTGTTACCGGGTAAATCGCCGGGATGCTACTCTTATATGTGCCTTCTCACCTGAAGCCTTGCGACCTCGAATGATTTGGGTGTGAGTAAGCACCCGGGATCGAAGCTGGTAAGCACGTCACCATGTTAGAGATACTTGACCGACGATGCCCTTCTACGGCTCGGTTCACGGTGCCCAGCGGGATCCTCTTATCCCAGCCGGTGCCTAGCCGATAAAAGCTCACAAGCTTAAGGCTCTGTCAGGGGAGATGTGGGAGAGGCTCGATGAGAAGTCCTAACGACACCAGAACCCCAATTAGCACACATGGCTCTTCCGGGGACTTGGCTCTCGTAACTGCCTGCAATGTACTACGTCGCATGCTCATGTACCAGACATTATGTCCGTCCTTAACAGTCGTATTGGAGCAAGTTGTGAGTACAAACAGTACACAAGCTGTAGGTCACTCCCCCCACGTCTACCCTATATACTATAAGTCCTTGTAGCCAGGATGAGTAGGCCCCGTGTACCTTATTTGAATGCGCACCCGTGACTTCTGGTGGAGAACTTGGTCACGTCGGGTGGACCGTGTACGATACCCCACAGTGCCCCAGGAGGTATGGAACGATGCTGCCCTGAAAGGTGGAAGGCCGGAGTTTTTGTAGTTACAAACAGTACTCAGCGCTATCAGCAAGTGGACACGGAGAAGTAATTGAATGACCGCCTAGCAGTGCTCCGCCTCCGGGCGGCAGCCCGCGTGCCTCAGTCAGAGATCTCGAGCACGCACCCTTGCTGCTTCCGACTAATGGGAAGAAGTGGAGATGGCGACCCCCACGCGTTATAGTCCCAAGGTTGCTTCCAGGAGCTATACCCGAACCTTTAGGTCTAGACTTGTCGAGTTTGCGACCGTACTCGCTTTGTATGTCGACTTTTTTGAAAAGACAACCGTGGCCCGGTCACTGTGTCTCCAGTTTGGCGAGCCGTAGTCAGTGATCGCGCTGCTCGGGATCAATTATCTCCAACGGTCAGCAGATCTACGGAGTCGGTGGCCGGTATAATGCTGGAGGCCGGTGTATGCAGGAACCTAATAGTCCCCGAGTGTCGATCTGTACGGGAGTCACTAAGATAAGGCAGAACTGACTATCTCTCCACCGCTACGTAGTCCAGTGCCAAGGTGTGGTCATGGCCCACATAAATCAAGGATTTGTATGCTAGAATTACGCGATCGAGTGACACTCAGAGTGCACTGGCTAAGGACTCTAGCTTTGTAAAGACAGCATTACATCAACACTCGTTGCATTCCTAGACTGCGGTTCCTTCGGGATCTCCCCTTGGTACTTCCTATATTTCCTGAGATGTGGGCGCAAACAAATGCCAGATCCCGCCTGTAGGCATTCGGGACGGGTACTACGCGATGACCATATCGAGATTGAATCTTACGTATCTCCCTACAAGTGTGGCTTAAGGGGTTAGCACCGACAACTCATATAAAAACCAAGTAAAGAGAGTAAACACAGTGCGGAGTAGCCGTACTTGCGAAGCGCCATTTGGGCGCGACCTTCCGAATTTGCATCCGACGTCGGTCGTATAGCAAAGAGCGATTCTGAGCCTCCAGTCGCGGCCACGTCGCCGCTTGGCCAATGTATACCAGTTGTGAATAGGTCGCGGAACGCTAATGGAAGTAACCCCTCCTATTACCAACACGCCTCAATCGTACCACCGGTACCCACGGCATATAGAGACTATACGGCGTCGCGGCGGGCCTCCTCATGCTCGTATGGACTACACACCATGTCCTAATAACCTTGGTAACATTACGCCTTTGAGGGGTTCTTTATCTCCGATTTCGCGGTAGATAAGGCCACATGACATTTTCCGTTCGAGCGGACACGTGTCGCCTCAGTAGCCTATTGCCGTCGCCCAACCTACGCCACTGGCTCATGCCATGCCATCTCATACAATTAACTCCCGACGTTCGTACCAGGTGTACCAGGGGGTCCATACTAAGAGAGTGTGACCTCCAGATTCTAAAATACTATGTGAGGAAGTCATGATTTCCTCTAGTCATTGTGGCACCGCTCGTACCGTGAATCATATCAGATAAGAACGATCAGTTTGCGACTGTTATTCCGAGGGTACAGTCTTTAAGACACCATTCGGAAACGAAAAGGGACTAATGGATGCCGCGAAAAACCTAAAAAGGAAACAAGCTATCGATCTGTGGCGCCAAGGAGGGCGGGGCCCCGCATGACTCGTCAACTCCCATAGGCACCGCTCCGGGCCGGTAGCGACCGGAAGGCAATTGCTACCCTATCATATAAATGATCCTGGTCATTAGTTGTGCCCCGTATACTTGAGTCAAGTATTCCGTCGCAGAGACTACTGCTCATCCGAGACAACTTCTTCTCTAAGCGACCCGGGCGGACAAATTCACACGCAGATGGGAATTACACTAGGGGTATACTCACCCGGGCCTAAGGAAGGCACATGAGTGGGGCGGGCTGATTAGCAATTGTATCAAACTAGGGTCAGGCACACATAATGAAGGAGCAAATACATTGCACGGATATAGCCTAGTCGAGTTCGACGCGGAAGAGGTAGGCGAAATAAACTGTGAAAATGGGCAACACCTCACGAATGGTCATGAGTCAATGTAAAATCTTCGCGGCTTACTCGGCCTATTGCTATCGTGACTCCCAGGCCCTCAGTCCACCTCTCGTCAGATACTAGTTCGGGAGGCTCGAGATAATTGACCCTCCCTAATTCAAACTCAAACGAACTCACGTACGGGTAGGGCACCTAATTCGAGATGAAACATGCCTAAACGCCTCGAGAATATGTCTGTTTTGTACATAGTCTGTCGCTTATTCCACCACTTCAATCTGAAAATAGCGGACTAGTCCCGAGGGCCCCGATTTGACAGGTGGTTGAGAAGATCAAGTTGCACGCTAGCACCAGACCCTAACTCGCAACTGCTCTGCCTGATAAAAAACACATGAATCTGCGAACCATAACCTTCTTTGCCATTCTTTGTCTGCGGTTAGCGATGGGGGGTGTAAAACCACCTGCAGCGCGTCCCGATGATAAGCTATATGGGTTCACGTGCAATCCCAGAATCCTTTGGGGGGTGGATCAAATTGAAGCGAACGCAGCGTTGTATCGACGGTGAGCCCGCACATTTGAACTCGTTCCTCGGGTTCTTCGATGAATGTGGACTACGCTAGTTGACAATGCCTGCAAGTCTCCTCTCTCCCCCACGTGTAATATTGTACATAGTCAAGAAAGCTACATGCACGCCGACGTATCTTCTGTGCTTATGGATCGTTATAAAATTTTGTACTTACAGTGAAAATATGAAGGATGAAGCCTTAGAACTCGCTGCGTGAGAGAGAAACCCACCTATAACAAGACGCACGTGGCGCACATCCGTCCCCAGTGTTCAGCGACAGTTTGTCTAGCCAGTGAATCGGATCAGGCGGTCCTAGAGGTCTAGGCGACTTATGATCTTAGTCAGTAACCCCAGTAATTACCGTGATTACCATTTACAACGGTTAATTGGGTTGGTCTATGGTAACGCACAAATTACTCGTCATACCTGCTTAACATGCCTTCGGGAGTTAACGCTGTCGGGCGGGGTCAGCTTACATTACAGTAATCCGGCAAAAGACAAACCAATGCATCTCAAGAACCAACATAATAAAAAGCCTTATCAAATCTGGATCACAACTAAACGTATCACAGTAATATGTATCGCGAGTCTAGGAACTTGAGCACCCAATCATCATCCGTGGCGTCTCCGCGGGCTCTGAACGAGAAAACTGGGCACTCCCGGCTACTTTGAAATCAGGAAAAGGTCATCTGTTAAATGTCTGTTCACGATAATAGGCTATTCCACTTCAATACATGAATGACTTAGGATAGATATTCCCCTGGGCACGATGTTCTTATGGAGTGCGGGATTTAGTGGATATTCACGCTTGTATTCAGTCCCCTGTCCCATCACCTTTTTATTTGTCCTCCGCCCGGATTCGTTTCGTGCACGGCCAACGAGGAGCTGTTCATCAAATCTACCGACATTAATAAGTCTGGCCTATATGTCGTCCAACTAGGGACCCCTTTCAGAGTAGGTGGAGCTATCGTAGTCATCAAGTCACAAAATGAGTTCCTTTAAGGTGGCGATGTGTTGGGTGCAGACAGTATAGATAACACTCGGCATGGCTTTAGTCCCTCTATCTCGGATGCGCGCATCACAGATACCGCACAGGGTCCCACCTTACATGTTCGGTTGGGACTGAGTGGAAAAGTTGGACCCTAATGGTTGCTTCCGCGAGAACAGAGACTTGAAGCAGTCAGTCAGGGATTCAGTCCGTCAGATAGGGGTGGAAGTATGGCCGGCGGCCATTTGAAGTCGGCTAGCAGCAAATAAATTGCGTAAATATGTTGGTGTTTGGGACAAGGAGGCACGGATCCAGACGTTACTGAGTCCCCGAAAGCGTTACTCACGGATACACGCCATACGCTCTACTAAGAAGAACCATGCACGGACCATTCGATACAGTCTTTCAAACGCCAATGAACCAGGAGCCGGGGGGATGAAGGTGGGTTGGAGGCATCGGAGTGGTTGGGAACTGGTAAACGAGAAGGCCTAAGAGTACTCCCAACGCGGTGGGTAGTATGTAGGTTGGTTTAAGTCGCGTTATCTGGAGCCCGATACAGAAGACCATCAGCTAAGAGTGGTCGTAAGACAACAGATAATCCAGGCATACTAACACCGTTTTATTAACACCTAACCCGTGCGCGGGCAATGATCTGTGATTTCGGCGGAACCCTTTAGCAATCACTCGAATGCTCCCCTCAAATTTGAAAGGCATGACCTCCGTTGTACGCCCTGGATTTCTTAGGGATCGATTAAATTGGAGGCGAATCGTGTGTCTGATCTATTGGCCAATTTGATAAATCGGGACAGAAAACCCTGGGCAGCTGTATCCCGGCCAACTTGACTTTCACCTTTATGCTATCAGAAAAATCGGTGAAACTGAAAGTCTCTGAAGTTCTCTGCAGTCATGCGGGTACACGAATGTGAATATGAGCTGTCGCGAGTTAATAGGACAGGCAGAAGCGCAGGTTGCGTCCTAACAGGAATACTCTTAAAGTAGGTGCGAATCGAGCAACGTCATCGCGTCAAGCGCGACCGCTTCAGTTGGTTGGAGGCTGTCGGCAGGTTCATCTTGCCAAATCGAACTAGCAGTGGCTTCGTTACGGGCCAATACCACCTCGAGGAACCCGGGTAATGAGGTACAGCTTACACAGGCAACCTGACAGAATGGATGTTTGACCTTCTATGCTGTACGTGTTAGCCCAACACAATTAGCAAGATTGCACCGGCGCTAACAATGTTAATGAGGTGTACTAAAGAGGTCGTACAGACAGGTCATGGGGGTAGGCGTATTTTCGCGCAGAACACGGGTCTATCCCATGAACGTACAGGCAAAATATTCGTTCTAGGAGCTGTGGGTCGGTTCCGTGGAGAAAAGTCGCAAGGCTATGTAAGCATTCATGCCTAATCCTCGCAAAAAGTGTGTGGGATTAGAAGCGTGTCTGAGCAGATGTGGTGCGGGATCGAAATAAGTAGGTAACTACCACAGCACACTATTCCAAGCAATAGTTCGAAAAAGGAAGACAAACCGATTCGGTTAAACTTGTGGCGGTCCTTTATTGCGCTAGCGTGCACATACTTATAACCGTTCCTTGCTAGATGCCAATACACGATATTGGCACATCAGGTGCTTTCACCCGAGACAAACGGCCTCTGCTAGCAATCCCGGGTCGGTAAAAATAGAAGACGAGAGGACGGCGATCATATCGTGCGAATAGTATCAGGCTTCATATGGGCAGTTCGCCTCGAGGACTACCCTCGTCGAAAAGCTTTACCGGAAGATGCCAAACCCGGGCAGCGGCACCAGGCTGTTACCCGTACTCCTAATAGCTCGGCTAAAACACGGAGAATGAAATACCTGTACCAAACGCACGTTGAGCTTCATCCACCTCTGGCGTGTGTACTATCCTATAGCGGATTTCGCCGGAGTTGCCTTTTCTCCTTGAGTGTTGATGCTGCCTTCTAACAAGCGCCTTTGCACCCAACATCGACATTTAAACTTTATTATGGGGTTGGTCCTGCTCCGTGCAACTGTCCTCTCTGTCACCACTATATTAAACATAGTCTGACCTAATGCAAGTTAGTAAGGAACAAGAGCAGCCTCATAAAGACTTGGCGACGCGTTGAGACACATATTGGGTACTTTAGGGATAATAAGTGTGAGGTACGAGGTGCGCGGACATTATCTTGATGCCCTTCTTGGAAATGTCGTATTTCAGGCCCCTGGTGCGGAAGAACTTTGGCCGGGTTTACATAGTTTAGATAGTCCTAGGTACATCAAGACGCCAGTATGAGTCCGCGAGCCGGTATGAGTCATATACAAGCCAAAGGGCCGCCTCCAACTTCTGTATCCGTAATTTTCTCCATAGGGCTCTGACCAGTATTGACCCCAAAATGTGGGCTGCAGATCCAAAGAGTTAACGGTACTACCCGAGGGATCAGTCATTCACTACGGTGCGCCTTGGATGGGATCCTACCGTTGAATTCGTAGCCTCCTGCGCTCCGCTAACCCTGACAATATGTGCACTTCGCCTGGACGTATTGACACCTGAAACGAGCACTGAGCGTAAAGCTAGTTGTTATACGTCACTGCACCATGTGGCGGGTTATAGCATCCTCCCATTTAGGTAATGCGAATCTTCACAGACATGACGGGGCATGTGGACTTACCGGTTACTTCGGGAAAACTGGCAGACAAAGGTTGGTTATAACCTACCAGCAAGTCATAATCTGTTTCAGGAATTACGCAGTTCTGCCGCTCATCCTAAAAATCCACCGACCCTCGCACGTGCCGAGTTAATCTACGGAACGCATAAGAGAACGGAAGCCCAACTGGAAGTTGGACAATGCCATGAGCGCCCTCGGACCACCCTCAGAGAGGTAATTTAGGGGAGCTAGGTAATGATCACGCTTTTCAGTGGTCCTGTATCGTGCATAGGGAAACCACTCTGGATAGTGCTTCTAGCGAATCGTCTAAGTACCCCATCCTTATAGCCCTGCCAAAGTGCTGGTAGTAGCTATCCGGATCACCACGTTCGGGGGACGGGGCGTGGCTCGTCCGTATGCTGGCTTCGCCGTAGCGCAGTCCGAAAACTGACAGACATAGTGCATTAGCATTTAAACCACCTCGAATAAGATTTGGGCAGATAATAGCGCCATCGTGTGCACTTGTTGCTCGGTGCCACCTAACCCCGAAGCTCCTAAGGCGCGGGCCTATAATCGTTATCCCCTACGAAATGCAAGTGCGTCCTTGCTAGAATCATTTGACTCTCCAGGGCCGGGAGTGATAGACCTTTTCAGATGTGTACCCAACGATGGGTTCCTACTCACGTAGATACCAGTTCAACCGCATAACCGTGAATTTTGGTCCGTGTCGTGGACGCCCGGAATGATAAGCCTCAACAGATTGCCTGTTTAGCTGGTCGATTGTGCCGATCAAGTTGACGTGCTAGGCCGGCGCTAAGCGTAGAGGAGAAATCTCGCAGCTTCGATACACGCGAGAACTTGGGCGTCACTTACATAGTCGGAGGTGTCATGGTTGAGCCGGTATCTCCGATTGATCACTCGGGACCAAACTCTATCTTCCTTCTAGAATCATCACGCCGACTTGAACACTGTCGTCGTTTATCACTGATAACGCTTATCAGGTTACGTGGAATCGAAGGTTCAAGACGGTCATGGAGCTGTTTTCTATTATTTCACTGTTAGTTCTTGGATACTGGCGAAGGACGCGCCACTTAGACTGTGCAGTCCCCAATTGGCTCGAGATTCCATCGGCGCGTCTACCTGACTCAATGCGTTACAGTCTTGGCCTGGCGCTCCTACCCCTGCGGCCTATAACGAGGTGGCTGTCCCGCGTGCAACACTCGCGAGCAACATGCCAAGACTTAGGTATAATAGCTTAAAGGTGTTCGCTTCTTGGTAGATAATTCTGGATCCGCGTGCCCACCTCCCTGTGCTACGAAGTTCCGTGAACAATGTCTAGATGTATAGCAGTGTGCAAGCCACCAGGTTCTATGGTGAGCAGCAATACAAGCCGTAGGTGACGTTCGGAATGACCCGCAATTTGTCGCGCCCCAGAGTAAAGCGAAGGCTTGACACTCCCGACTAGTAATCCCATGTGTAGGCCCCAGCACTAAAACATCTCGTTCCTCCTCACTTCCTGTGCTCAAGCCGCCTGGGGTCGAGGCGTAAGTACGGTCTTGATTGGTTGATTTTTGGACAATATGATGTCTCTACCAGCAACGCCGCCACCGGTTATGTCAGTCTCTGAGTTATAGCTACAATCTCAAGAATGTCGTGCGGCTCCCGTGGATGGCAGACGAGTCAAGACCAATAACAGACGTGTGGCACCTCTGGTCGTATCGTCACCCCCAATTGATGAAAATGTGGCTAGAGTTCCGAGGAGGACTTGCAAAACGAGTATCATTGATCCAGCCCATTACTCCAGTGTCCAAGCCCGAAACTGTAAGAGGGCCATTGAAATAATACCGGCTAAGGAATGTCTCGGGCGTGCGGGAATCATAAGGATCCCTCAGTTGACGATTGGGCGCCTCTTTTGCGAGCGGCATCCGCTGCATCGAGGTAAATATGTGTTGGGGACACAAGCCGGATTGGCATTGCCGGAACTTATGTGCGGCAATTGCAAAAGTCGAGTACTAGAAGGATGATCAATTGCCGATGCGCCAATTGAAGATGATCGCCTAAATTGGCTTGTTCATCCTTCGCTCCTGTACGAAGAACTCTATCCAACAGTTGATGGTTGGCAGTAGTTCCGCACGAACAACAACGGGATGGAATTCACGGACATGTTGGTGCCTAAACTAGCGCCGGTTTACCGGACGTGTCCGTACTCATTCCCGCCGCGCCAGCCAGAAAGGGTCGATAATTGCAACCTCTCTCGCAGTATCCTTTGGTCGGCAGAACGCCATGGAGCGATCTCCTATCTCTCAAGGTCAGTTTAAGAATTATGAAGTACTTCTCGACGTGTTGAACTTCCGGTCTCGGCCGTTAGGCTCGCTCGATTGAAGTACAACAGAATTCAGTTTAACCTACTACTCGCCCCAGAGTACTTCCTATGAATGGCTGAACTCTGACACCGAGTAGACAAGTGGTGGATATACTCTTTACGGGAGTCACGTATATCGTACTATTATGTTTCAACGGTGCTTGCCATCCACCACAACACCGGTAAGATTATCAACGCTTACTCTCAATATTGCCCGCGAGGAGGTCTTATCCAAGGTGTAACAATAGTAGTCTGTAGCGTTGAGATTAGTCTTAGAAACGGTGAAGGGCGTTCTCGTGCGCTCGATACCGCTCCCCCCCAATCGTGTTCGGCATCACTAGGACATACAGCGGTCGCCAAAGCCTTTCACCGGTATCGCTTCTCGGGACTGATGCTGCAATACACGCGTAGTCGAAGCAAATTTATGGTGCCCAGCATCTGAAGCAACTCCATAACTTTTACCGTCGATAACAGGATTTGGTAGTCCGCTCGGTACTAATGCCGCAAAATGAAGCCCTATAATGAGATATCCTAAGGACGTAGGGCGCCATTGTTGGTTAATTCCCCCTACGGATTGACGGGCCGCGCCGTCGGGCTGGGGTTCGTATGAACCTAGCTCCACGCCAAGACCTGTCCCTTGTCATAGCCAACAGGACACCTTTCATTATGGCGCTACGCATATGCGACTGTTCCCACAGTACAATGATGTGCTTAACCATCGTCGCTCGGCGATAGGGTATCTTTTAACTATCTTAGACTGATAACGTGTGGGCCGATAGTATCTAAGAGCTGTGAGGCTTGTGGACCACTTAAGCTATCGACTCCCATTGGGGCAAGTGATTACCCGGGTGCTATCCACAAGACCGCACTTGTGTCCTTGCGTCGAATTAAGAAAGCTATAGGGACCAGCTGATATTAGGTGCTGAGGAGTGCTACCGGCCTGTTTCACATATATCAGAACGCGTGCCCTGAACTAAGACTCAGCCAATCAATACTGCGTTGTGGGTGAGGCAAGTATTCTGTCCGGGGATGCTGTGGGGGACAGTATTGATCTATCATACTAACCATAGTCGACATCTCAGGTTTTCGAGCGCTGACGGTACAGACAAATTTAGGGCGCTACGAGAACAGCATGTCGCTTGAACCGACTCAGGCGCCGTAATTAAAGGGAGTGTGCCATGAACTCGAACGCACTCCGTATCAACGCAGAAACCGCCTTACAACACTGAGCGGCGTAAGAATACTCACTCGATATTGATTACCGTAAGGCTATATTTGTATGGGAAGCAAACGAATGACATTTCCTGGATATACAACAGTTAGCTGAAGGCATATGTGATCTGCCAGATTCCAGAAGCTGATGGGGGATCAGGATGAACCTTGTCAAGGATTCGTATCTGCGCTATACAGGGAGAACTGTGCGATTGTTGAGGCTACGCCGCGTAGCCGAGCCGTTGGAATAAGCAGCCCCGTATGTGGACATTGGTAGGAGCATATTCAACGGGCCACTAAAGGTCGCAATTGCCTACATCAGATGAAAGGTTGTTACCGGGCTAATATCATATAGAGCCCTCTAATATCCACCTGTTGTATGAATACTGTCGCAGTTTCATCACGGTTGCCCCTAAAACACTGACAATTAGGTAGCGGTATCGTTTCTCATCTACTCAAGGCGTATCTTGGGTCGCAGGGGCACGCCGTGGTTGCTCGCCAGTTACTTACTGACGGTACCTCTCATTCTTTGCAATGCGGGTACTTGTGTCGTTGAAAGTAGTGGTACTCGCACCAACTCAATCTATCGCCGCTGCGAGACAGTCCCCGAAAGCCTCCGCAGGAGCAGCGCTACCTCATATCCTGCACGATTAGAATTAACTGCCTCTCTAGAAACGAGTCTTACTAGTAGTTGACCTTGATTCTACGGCCACTCGCATCGCGATGATTGAGAGAGTTCCCCCACTCACGAATTAGGAATCATGTTGTAACAGCGGTCCCACTTGAAGGTGAGTCTCCATACAACGAGTACATACTTGAGCAAGCAACTAGATTATCAAGAACACGCATTTGTCCTAGCCTGAACCACTTTTGGTCTCACATAAGACAGCGGGAGAAGCGATTCGGGCGACGAGGCTGTTAAGTCGCACGGGTTGCTATTCATATAACACCTCGCCGTCGTGTTAATGATGTTTATGAGCCCTGGCGGTATGCAGAGCTAATTGGTTTGCATGGGTGAGGTAACTTGATTCCGTGTTTGGTAACGAGCGGCGGTCTACACCTAGTCTCGGCCATTGGAGACTGTTCGCGGGGGTAAAAAATCAATTATACAGACACTCTAGCCTGATATTGCCCAATTTGAAAGAGTTCAACCTTTCGCAGTTTAGTGAAAACTGAGCGGTTTGTGAATATTACCGGCCTTATATATCAAATGGTCCGGTACCAAGCCTAGACATGTTCGGACTTTGTTCCGTTAAAACCGAAGATTACGCATTTCACGACTCTAATTTTTAGAGACTGCTAGACAGGATATCAGCCACGGTGCGTCCTTCCTGTATCGCTACGTACTTGCTCCTCGCCTTCTATATAACGGTACTGGCGAATTCGACAATACCCTAATAGGAGCTGCGACTCTCTAGACGACCAGCATGCAGCTTATTTAAGTCACACAGATCGTAAGAGAGCCTCGCAATGCTCAGGATATCGGCTGCCCTAGAGGATTAGCGGGAGTTGGCTGGCGCTATTGAATGTGTCAGCAATGGCAGCTCCAGGATCGTCCAAGGAGCCGCTGGCCCGTCCCATATGGTCTTCGTATCAGTACTGATCAAAAGGCGCAGCGTGAATACGTTTTCCTCCATAACATCCAGTCAGTAGCTGATAACGTTCTCACCCACTGACTTCCAACAGGGGCGATGGACCTCCAGGCGAGCCATGGAGTTCGACCCCCTTGAGGTATAGTGTAGGAACGGGATAGGGATTAAAAGCGTTGTGGTTTACTCTAAGCAGGCTAAGAGGCATAATGTCAGCCCATCAGCGCGCGGTTAGACCTAGCCGATTGGCGCGTACCAGGAAGCCGTCCGTCAATTTACAATTGGTCGTAGTCGGGATACCATCTTGAAATGCGTAGTCCGTCGCGCTTCGGGGCGGGCTTGAAGTGATCATGTGCACCCTTTAAAGCCATAGCCATACAACGTACCTCGGCTGAGTAGGTTCATTCTCTTGGAAAAATACCGCTAAGATAGAGACACCTAAAGTAGGCTTCTTAATAGGGCATGTGTTTCCGCCTAGCGTTGACAGCATGTGATTAACCACTTGACCATCTGTCACGCGTCATGCTGAAGCTTACCCTTGATACACGGGCCGTTATCCAGACGCCTGGAAACTCGAATTCATCAAAATTCCTCCATTTCTCTGGCCCGACAATCCACTGTAGAGTGGGATCGGTGTAATACCCTGAGTTTTCTAAACGGCGACACCGATGCTATTTAGTATGCCACGCGCTTCGTACTGTTGAAAAGCAATTGGAACTGGATGTCTATCCCGTACTTTTAAGTCGTAGATCCGCATCATCCATGCTAATCGTCGTCATTAACCAATCACAGTCTTGCAAAACTCACACTGGCTGATTCTGTCCAGCGTTACCGCGGTCCTGTCCGATTAAGAGCTCTCTCTGCCTATTTTCAGTTCCCTCCAGGCGTAAGGGACTTGATGTACACGCTCGACGAGTGCGGCTCTCTGTGACTAGAAGTCACTCGGGCTAAAGACGACTAGAGGTTTTTTCTGCGATCTAATATTAACCATACCCTACACAAACGCCCACCGGTTTTTATCACAACCACAGTAGCGGAGACGTAAATCGTTGTGCACAGAAAGTTAGGTAAGTTATCAAAGGGCAAAAGAATTACAGGCCATATTCTTTCAGTGTGACCTTCGAGTGCGGATTAAGTCCGCGGCAAAAGCCTAGGGACGACATCTTAGTAGGCTATCTCCACCCAGTATCTGGCGCGACGTCAGGTGTCAGTACCATGCTCTTATGCCCCCCTTTAGGTCCACCTAAACCTCGAGGTCAGCGATTGACCCATGTAGATACTGGTAGACGTCGGTGCCACTATGATCGGTTTTGTCGTAATTCACGAGCATTTGTCATACTGTTAAAAACAAACTTTGACGACAGTTTGGTGCTAATTTGAGAACCCACGTGGGGCCTGCCGCCGGATGTACGGTATGATCTCACCGGGTCTCCATGATACCCCCATCAGCCTCATGTTCTGGCCCGTCCTCAGAAGCGAGCCCTCAGTCCTTTCTTAATCTCCAGTTACTTATCAGGGAGTCCAGAAGCTCCGGGTCTTCCAAATCCTCCGCGATGTCTTAGTCGACCCTAGGGACACCTAGAGGATAGTCGCATTTGTAGTGTAGCTGTCCGAGAGCAGAACGCTGCGGCAGGCGGACATTGAAGTTACGGCTATGTTATCAGTCATCCTCGGCTTATAAGAGGCTTTGGGAAAGTTGGGTTAGTGGCCCAAACGATGATATGCACCAACCAAACTCTTTCACAGCAATCCCGCAGAATAATTGCGGCGCGGACGGGCGATGGGCCAGCTGCTAGGGTAGCGACAAAAGGACCACCAGCTTCTGTCTGAAGACAGGGGCCACCAAACCACCCTTGTCCAACTCGTATGCCCGAACAAGAATCGAGATCGAATTGTCACTTATCATCCCGTACACAGTAGGTCCCGTCTACGTATTCCATGCGTTGCCGCAGGATTTACACCAAGTTTGGTCGCCGGTCCTCACTCGCTAACTACAGCTGTGTAAAGCGCGGGCGAGGGCGATGGATACGTACCCGAGGTTATCAGGCTGAATTGCTGGTGAACACTTAGGTACGACTCATACGCGGGAACCCGGCAGAACTGTACATTCGCGGTTTTTGTCCTCTAGCTATTTCCAAGAGCTGATCACGAGAAGTCTCTCCACGCACATCGCTGAAGCGAGACCCTCGCCAAGTGTTACTTATAGACTTCTATGCGGCGCCGCAGTTTATACAAGTCCTCGCTCATTTTAGTTCGTGCCTACACTGTCACTCCTACGGTACGCCACGGCGCGTGGTGATGAAAAGGTTTCAAGTTCGTATGCGAAAATACAGGCCATTTAACACGGACTCCGCGTCCGGGCGGGGCCGTAACGTTGCCCGTACCCGGACAGTTCCATTGTGAAGCACTACAGCTTCAATGTTACCAGTGTAACGCCAGCATCAAGAGTTGCAATGGTCTAAGCGTCACCTGAATTTGCTATATCCTGACGAGACAGGCGTGCCCCATCGGAATGGCAGAGGTAATAGGCAGCATCCCCGCGGATCTTCATCTGCCGTCAACAGCGCCGGATTTGTAGGCGGGGCGATAAGCACTCGGGGGTCATCGTTTAACCACCAAATGGGCAGTACAGGTGTTCTCCTGTCGGGCCGTGTAGTTAGTCCGACAGGTGAAACAATCTGTCAACGAATTGGCGCCTACTTGGTCCGCCAAGTGAGATCTTGAAATTACAAGTCTTTCCGGCGCAATCAGGCCACGATACTGGGGCAACACCCCGTTGGGACGACTGGTAGAAGCTGGACTCCGGGACGGGGCACAAGGCGGTGGCGGCATTGAACAAGCACGCACGCTCCTCCCTATACCTACGACAACTTAATCTTGTACCAGACAACCTAGGAACCCTCACTTGACTGCTCAAGCCGAAGGGAACAACCCCCTCCTTGGACAAAGCTTACTGCCAAGGCTTGGTACGTTCGCGTGTCCGTTCTGTATCGGGACCTGAATTGCGTGTGCAAGCGTCATTCGCCATGGCCACTACGGCCTGGTCGGGCACCCAGTGTGATAGTCTTTCATGCGAATGGCCCAGTGCTATCTTGTTCGCAACGTTCTGTAGATAGAAGGCCGTGGAAACTGCGACTATCCGCCGCACAACCTTCACGGGCCCCGCCTCTCTATGGAATACGTGTCTCATGTGCGATATGAAGGTTGCCCTCCATAAAGCAGATAGTGCTGATGTGCACTACTTGGTACTTTGAAACGTATTAGTCTCACCTGCTGATGATTCCTTTAAAGCGGTGCAAACAGCCTTCGGCAACCGGCCACTTAGGCTCGACGGACACCATGCCTTTCTGACTTACAAAATGACCACGCCCCTACGACAGCTGTCGTTACCAGGCATGCCTTAGCTGTCAATGGCCTCATCCTGCCTCCTAAGGGGGTATGTTCTCCTAGTAGCCATGTCATAAAACCCCTGCGCGAACCGGGTTATCTACGAACAGTACGAACCCGGCGCGTTTTGGCTAAAGTGGGGTTTATTCAGGGAGCCCGACATACCACAACAGTAACAATAACACACTAGCCGTTAGCAGGGTCGACGTGCTCCCGTTCGCGGAATTCTGGCTGAACGTAAATACGCACCTGAGCGAATTTTCCACGAACACTTTTACATTTAACCTCGCAAGAACCCTCCCCATTAACGAGCTGAAACGCTTATAAGAGAGACGTAATGGATCAGAGACCATCTCCTCCGAGAAAAGTCTGGGTGAATCTACGATGGGTATCTGGAACCATGCTCCCTCTTCCGGAGGACAAGCCCTTAATATGGAATCCAGACTAAAGCCATAGCGATAGCAGCTTAAAACTAAGGCACGTCGTCCAGCCAATTCGGCCGATTCCGTTTGGAACAAATAGCTGTCTGTCGCAAACACGACCCTGGGAAATGATCCAGTTCTACCGCACCAGAAGCGACCCACCCCGTATTCGCGTGGTGTTCCTTCAAAAACGCCCCCTTGGGACTCAAGACGTCGAACTTCTTTACCCCAACCGTTGCGGGGTGTGTGAGAAACCGCAGACTTGAGAGCCCGAGTATCTAATGCAATCTTCTCGGGTAACAAGTGTGTGTACATCGTGACAAGTCCTTGGGGTCTGCAACAGTATGTCCGACCAATTGACCGACCGCAGCATAGTCACAGTCGGAACTTTCGGAGTAAATCCAGGAGGGACGCCTATAAACTGTTCATAGGTGTCAAAACGGGCAAGGAACCAGAGAATGATTCAGTGCATTCGAAGAGTGGACGCGGTAACGACGTATAAATTTCGCGCTTCCAAGTAACACCGGACCGCGATGTGTGTCGCATACCGAGTTCTATGACGATGCTCAGAACCTTTGTCCACTAGCTTGCAGTTGCTCGACCCTAAGCGTTGATCCGATCTGTGTACAGAGAATCCACTTCTTATCTCCGTTGGCCATTAAAGCGTTTGTGTCCAGATCGGACTTGGTGTGTATGTAAGGCCTGATACCGCACAATAGGAAATATATCGGCTAAATTAAATTGGCTCGGGATAGCCGATCTCGAATACGTCCATTACTGAAGCAATTGGTTACGCGCGAGCCCCCGATATTGACTTTGATAGTATGTCCAAACGAGTACAAACTCGTTGCACTTAAGTTCGACTTGCTATGAAACATAGCCGTAGGAGGATTTAACCGAGCCACAGGCGGCTCCCTCTATCTTAGCGGATCGAAGTAATATTCTGTTGTCATGGCTTTAATTGGGAAATGGCTGCCGAAATTTGGCGAAAGATAACAAGTTAATAAGGACAATTCCTACTTACCAAGGGTACTGTTTCGCAGCGGCCGGTACCCCTTCGAGACTCTGTTGATTTTCCGTGTACACAGGCAAAATGCATTGTATATCCCGGATTGCTTGCTGCTCATTAGGACTTTACGACATTAAAAGCAGACCAATTTGACCCTGCTAACCATTAATCAAGGTAAGCTGCTCTTTCACGGAGAAAGCGCGTGTCTGACTGAGTATATCTAATAGAGTTAGCGTACAGTAGTGATTGGCATGCCATCGAGAGGCGACGTCCGTAGTCAACCTACACCGTTAGAGAACCCTTGTCCGTTGCGCTTCTTAATCTTTTGTCGAAGAGGAAGTACATGAAACAATCAGATTAGTCATTATGATACACATCGGTTGGGACACATAATCTTTGCGCTGCAATACCCTACAGTGGCTGAAAGAGTGGCGTTGCACGCGGACTAGGATTACAGCGTATGCCCAGGTTCTTCGTACGTTCCTATGGGGCTGTAACTTAGTATCAGACAAGCTTGCAGACCCGCGCCCGGGCACCGTGCTATCTGAGTGCATGCCGTCGGCGTAAATCGTGCAGTGATTCTCCTCCGCCAACGGCCCTGAACAGGGTTCGGTGCTACTACTGTGGCAGGGGGGCGGGGTGTATGTTACCACAGAAACTCCTCACGCGGCAGGGTTGACGGCCAGTATACGCTATGAAAGCCAACAATTGGAGTATGAATCCCTCACGAGGCTTAGCGATGCAGAAGCTCGCCTGTAGACTAGTCTTACTAAGTGAAGAAACGGCGGACGAAATCGAACGTGGGTTATGCTTCGATAGTCAACCATGAGTGCATTCAGTAGAAGGTCGGAGAATCCACTAGTGTGCGGAATTATGGGTTCCATCTAAGGCGAGAAGGGTCCGGGTTAAGTCCAGCTTCTACACTCAGCAGGCAAACATACGTGGCCAGGCTCCTTTTAATCCCCGGAACAACCCACTCCGGGGGGTGATCCCGAAAGATAGATTTATGTTGAACAGGCAGTAGCGATTAAGGCAGCGGGAGTGGACATATATAGCAGCAAATTGTCTCCCTCGGGCCTTAGCTCTAGCTCCGGATAACATAACATACCTGTGCATTTGGCAGCAATGATGATCTTGTGCTAGGTTGACACTGGTTGGCGGACAACGCCCAGTAATGGGACTAGCCTGTGGCAGTTTGAGTTTATGCGTGAGCACAGAAGCGCGCCCGTCTTAGGTTGCTTCACACGGCCGATGTCACGGCAAATTGGTTTCCAGGGAGAGATTGACGTGTCTTGAGTCTACGCTCCGCGTTAAATACACCCCCCCTGACCACGTTATTGTGCGTTTAGACCTATTCAGTTCAAGGCGTATGGGAAGACAGCCCGGTAACGTCGCGGTCGATGTCGAGATCCGCTGCGCCCGTTCATAGACGACAGCATGAGAATCGACGGTCTTGAACGTTAACAGATCTCAAAGTCGTTAGCATAAAGCTCCTAGACCAGTCCGTATTGCCGAATGTCCTTAGACTGATAGGCTATGGCTGCAGACTCACGCATCAGCCCGGCGGGGCTTCAGCGATCTAAAGCTCGCTCCGAAGAAGCTCGGGATACTCATGAAGGGAACTTGAAGAGTTATATCGAGCACGGAGAGACCACACATAGCCCTCTATAGATTTGTAAAATTAATGGGATTGTCATACATGCCAATGGTATGGGCTAGAGGCGCCTGTCAGTCAAGGAGATAATTCGTACTCCCTTACTTCAGGGTAGATCATGACAGTTCAGGTGAGGTCATCTAAGGAAGGTCGCTCGGCTGTAGGGGTCTCGTACTATTAGCCCACCTCAGCCCATCCGCCTTCACTCACATATTGTCCCCCTGGCCTAATGGAATGGAAGGTGATCACTCTGGTCGGGTACTACCACCATATAAACACTGTCGCTGTAATTGTGTTCACTAAATACGCAGTCGAACGTCCCCAGTCCACGTCCGGGTGATGCCGCGCTCCCAAGTGGAAGGTATCGATTTAGGAACCATCGATGCTAAAGACTGTATCCTCGTACGCAAGCTACCGGGAGACACCTCCGGGAGCAGTGTCGGTACGCTTGTATAACATCCTGACAAACGCGTTAGTTGAACATTAGGCGTGGTTCGCAAGGTCGGCACTCGCTGAGACAGTGTAAAGTTTGGCGGCTCGTTACCATGAGGCCTTTTCTTCTTGGGAGGTGTTAACCCAGGGCGTGTGCGTATACGCCATAGGACTTACTAAGTTGTGGACACCCGCCCGCCTTTTTAGTTTTAATAATGCCCGGCACCTTTGCTTATGCGATTGCAACATCGCTGCAATAAGCTCGCTGGACGTATCAGGCCGGAGAGATGCTATCGCGAAAGGATTCTTCCCTCGCAGCGCGTTCGCATTCTCATTTCGATAGAGCTCGATTAAATCACGGAACGCTATGGAACAAGTGTGCGGGACCGAGAGCAAAACGCACGTGTTAGCACCTTGACCTAAGAATTGGGGATAAGGATAGCCGAATGAATGCACTTAGATGCGTTTCGCCGCCTGCTACCACATGAGCTGAGACAATTAAGCGCAGAGATCATTGGTGCTGTCAGTGCAATACCTATGTGGGCCGCCTTACACTAATTAGACATCCGCAGCCGCCCATTTGCGGCACGAAGGGAAATCCGTTAAACACGGGCCGTCCGAAGTCCACAAGCACAGGTCCGTGACCCGTGATGGTTCTGTTTTAAGCCATCTTTTGGCGTTCTGTCGATGAAATGCTGAGGTTAAGTGCGCGAAGTTGCTTTCCGACGAGACTGCTCCCTGCCGGCGGGTACGCGTACAGACCCTGCGGTCCGCGGGCGTGATCTAGATTACAATCGACTTCCACGGCTATCATCCGCTCGTTTGCCATGGAGTCGTGACAACCAGTCTAATTGGGCTATATCCCCTGCGCGAGTACTCCGCGGCCATAGGTATGCGTTACAGCGTTCCGGAGCAAAGCGTGCACTAGTATCTTCATCCATGAGGTAGACGATAGGGGTGGGATCGACTCCGATGCTAATGTCTAAAGTCCCCACGCATCTATGTCCCATAACACATGACCTACAGACCTTCTGTTGTTAAGATGGTGTTTGTCCGATGAATCGTAAAGACTAGCTGACTGTACGCAAAACTAGGTAGTTTGCTATCTGACCATGGGGTTTGTCTCTGTCGCTTTCGAGGGAATAATTAAAATCCGGGATGCGGGTTTCAGGCCCACGTAAGGCATCCGACTATCTACCAGCATACACGAAATTCTAATGAGTTCAGATGCCGTCTAAACAGCTGATAGTGACTGCCATCCTAGAGGACTCGCTCTCTTCTTACCCATGAGGTACTGCGTCGGAGTTTACTGACCACCCCCGATCCAGCTAGAGCGATGAAAATTAAGTTTTACGGACCATAGATGGGGTGTATACATTTACAGCAAACAATCGCCCTTGCTCCTAGAGTTACATACACGCCTCTACGACCTGCCAGCCAGATCTCGTTATCGCCCAAGGCAAAACTTACCGCAACGCGAGGCGCCTTTGGGACGGCTGCCTCATATAGCCGCCATACACATGACTACCCAGCGACGTTTGTAGAAGCAATGGGCGAAGAAGGACGATTCGAACACTATCAGGGGTGCTTCAGTTTACCTGGAAACGACTTTCTCTGCGATCCTATTCACGTCCTAAAGCATCTCCGCTAACTCGACGTTGAGATGAGCCATTGGGCTGGAACAACAGTCAGCCCCTAATGAGGCTACCTCGACCAGTTTTGGTTGCAAAAATCCGCCCCCGGCTCTCCTTACAATTTGCGGTCGCTTAGAGACATCATTATTCACGGTCGCCAGGATACTATCCGTACGAGACCTATGCGTAGATTTAAGACCCGGCATTCGTTTTTCCGGTGTATAATGATTCAGTTATTACCATCCACATCTAACATCAAGAAAACCAGCAGGCGTGATCATGCTTTAGGTGGGTCCAGAGGATGACGACAGGCTCTTGCTTATATCCGTTCACTACTGAGGTCCCGGGGACCCACATAAGGAGCATTGGGCAAAATACGATTGCAGAAGGCCGCAGCTGTGCTACCAATTCTTGCCTTCCGTGTTTCCCTATCACTAAGACACCGCAAAGTCCATCAGGTCGAGTCATCCCCAGCCGGCAAGCAGATTCAGGTAACTACACAACCTCACTGAGCAGCGACGGCTTATAAAAGTGCGTTTGTTAACTTAGGTCTTTAGCTATAACACGTGGCTGATCACACTCATTCATGTATCATCGGCGCTAATGCGGCAAGTGGGAAGACATCTAACCGAGGGTAAGAGTTCTATCTTAGATCCGGTATCGTCAATACTGACGCGAAGTTGCGGACCATTGGAGTGCGCGCCCTCTGGCTGTTTGGGGTATTTCATCTCTGAACATTTAAACATGTAAGAGGTTGAACGATCATGACTCCAACCACCTTCGCCCAATTCGAACAAGTTGACGGCTGTGTGAGACCCGCTCATAATACCAATAAAGAAGGTCACAAAGCTTAGTGCACGTTTGATGTGAGCCCAGCCCGCTAGAGGCCTGCTAAAACCTGCAGCTGACAGGGGCGCCAAGACGCGAATCTGTTGTATTACAAATCAAAGAAACCGACACATTTTAGACTACGAGCCAATTACGATATCGGGCCCCCTTCCCGCCGAAGAGTTTGTCAGTCACATAATGATCGTATGTCACCGATACCCCTGGAGGGTCCAAATATAAAGAACAGTCATTTGTAATCTGGGAAGTCACAACATTTATGACAGGAGATAAGGTTATACAGCCTTGTAAGACTCGGATGATAATATTCGCTCTATTGACTGGCAAGTATTGCACTATTTGCGAATTAAGAAACACCCGCGTCCCAGCTCGACATTCCCGAGTGTTCATTCCTGGTCCCATCTTGACCGGGTATGGACTGGGTCCCTCGATGAGCACCTGTTCGCTATCATGTGGGCCGATACATCACACACCCTGATCAGGGGAGTGCCGAATTTGCACCGTCCCTGTGGCATGAAGTCTGGTGCACCGGTTACAGGGATAGCCATTGAATTCAGGGCCTCAATGTAACCAGTAAGAGCAGTGGGAAAATGCTGATGAGTTCGGATGTGGTTGTAGTCGACAGAGTACCGCGCATACTGCTTCTTGAAACGTCCGCGAGGGGATATTCGGCTTGTCGGATTATGGAATGGGATCTCATAAATCTTGAACAACGAAACACTACATGCGTCCCGACCGTGCCAAGTCATCTATTTAGAGTGCGCTTAATATATCGTAAGTAAGTCTGCAACTGTTCCGGCCGTACTTCTTTGTGGTTCCTCACAAGTATGAACCTTGTGCTCTATTCCACCGGAAGCTGGTGACTGCAATCAGAAATCGACCTGTTCTCGTTGACTGCACCGGCTGACGCTTTCATACTCTTATACGGACGAATGAATTTCTAGTTAAAGCCGCGACTTTTTAGGAACAGAGGCACCGGTTGTATCTTCGCCCGGAAATATTGGCAGCTTTTGTTGCGTAGTTATGGCCATACTAATACCGCCTCATTAGTCTATATTGTTTGGGCACATATATCATCACGCGTACCCGCCCAGTACTAACCATCAATGGCCTCTACGAGACAGTAACATTTTAAGACCCTTAGGCGACTCAAGAACTTCTCAGCAGGGTTCTCGCGAGATCATAATCTATTGCGGTTTCGTTAGCCATAGCAGCATCTTGTATTGTTATCATGTCAGGTATGCGCTCTTGTGAGTCTGACGAGTGGTCTTGTTAGTCGTTTCCACCGCTCGATGCGAGTGAGTGCAGACCGCTTCATGTTCTTCGGTTGCTCGGAATGGAATGGGGCACGCAGGCGACAGCCTACCGTCCTGCCTGGCGAGGGAAGATTTCAAAGTCGCTACCCGATCTGGGTTGTTTCTTAGTCGGCATATTGGAGGCGACTCATAGAACGTTACTTCAAACATGGGATTTCATAGTTGTTTTAGAGCCGCAAGTCTTACCACACGATTGCATAACTTGATCGTATTGCGAAGTTTGAGTCCGGGAAAAACAAACCTCTAATGATAACACATGTCTGCCGGACCGCCTTGCAGTTATCACCGATCCGGTTCATAGGGTAGCCAGCTTCGTATGACCTTAGCCGATTACTGTAGAGGCAATTGCAAAGTCAAAGCGAAATTCAGGCGTACCTCAGACATAAACGGGAACCTCGTCAGCAAGATCGGTAGACCTAGGCTACTCACGCAACGCGGTATATGCCCGGTTACTACGCGACCACGTGATGTAACCTGCTGTGTTTTACCTGGATTGCCATCGCTGGCAGATAAGTATACTAGTGATCGTGTATTCAGCATTAGGTTATTTAGAGAGAACCATCCACGTCAGGTTATTGTTGTTAACATCGTGTCGGGCTCCATCAGAGATATCCGATCTACCCTGTCAAACAACGCGAACACGAGACAACTTTTTGCGGCGCCATTTGGCCGCCAGCCGCAGGCCCCCAACGTGGTCTTACCATGAAGGGGAAGCACTTGGACGTGAAAACTGAGGTCGATTTAAGTTTGACATACAGGACTCTACGATGACCGTCGGGTGACCAATAAGGATCTACATCTCTATTCTTCGTAAGCACTGATGGTAGTATTCCAGTAATGGGAAGCTCGCAGCCACTTTGATGCTCGTTTGATAAACCCATATCGACCAAGAGCCGGCGGAGTGGCGGTTTGCTTATCAAATTCATACAGCCTGAATTTGGTTATCAGATGCCTAGCCCCTGAAACTGCAGCTCAAGCCACTGACTACAGAACTGCCCGTTTCGCCGACATCAACCCAATCGAAAGCACGATGAATCTATCGGTAAACTCATCTGTGGATCCAAACAGCATCGTTGGCCAGTACGATTTTTGCATCCCCTAGGACAGGCGGGTCCCTAGTCCGCTTGGGGCCACAGCTTGAAGGATTAGAACAAGTCGTGAGGATAGTGTTCTGTACTTTACTATAAGTATTTCGAAACTATCCATCCGTTGAGTTGACTCACGTTCGCCATGGGTTGAAGATGGACCTTCAATGGTCCAGTGTGCGCAAACAACCAGTAAACGTATTATCGTATCGAGGCAAGCGACTCATCACGAGCGCCTCGTTGGGATCGCAGAAGGGACGTAGCTGGTCACCCCAGCTATTAGGCCTGCATTGACTGCCCGCGTCATAATTCGTGCGACAGTCTATCCCGGTACTCAGCTCTACGTTATGTCTACTAGATACTCGGCTCTTGAACACCTTCCGGGCAGGACCGGAATCCCTGTTCCAGTGCACGATAAGAAGAGTTTTCGCTTCACTGCAATAAGCCGTCGATTACACAGTGAATGTAAAAAGAATGCTGGCCATGAAAGCATTGTACAACCATGCCCAGGAGGGTCTCGGACTCTCTTTCGGACAACCGCACTGGCCTTTAGAGCTGGAGCGCGGGTAAATTTCGAGGGGGTCGACTTTTTCGGGTGATTCCATATAGGCGATGTGAGACACGGAACATAATCTGTCACGATGGATGTGCCCCATGACGACCGTTGACGTACGACAACTCGAATTCAAGGAGAGTAACGAAGCGTCCGATATAAAGTCCCAACGTCTTCCGAGATCAGACCCAACTAGAGGATAATATTGTGCCAATAAAGACAGGCAAGCACTGTGGGGTCGTCAGTTTTGAGCCTAGCGTATCGGCAGAAGCTCGCAAATAAAGTCACTGACGCACATCGGGTAACGTGGTGTCCCACTGGATTTAGCATTGCAAACGGCTCAGAGCGCGGGATATCGGTGTTCTCGACTCCGAATGTATTGAGTGCGCCGAGTCGCCTCGTTATTCCGGCTTGAGTCGCTCTCTTCTGGGATATGAGAGAATGCTTTCAGCCTCTGACATCCGCCGCGCATGAGAGAGAGATGGAGATAATAGGGTGTTGGCATTCGGGAAGGGCGCTCAATGCCTACCTCGTTCCCCTCATGGTTCCCGCCTTAACTTGAGGAAAGATGGCCAGTGTACTCGGACCCCCATGGAAGATTGGTTTCCATAGATTCCAGCAGACCTAAACGCTATCTGTTCTAGCACGTAGGTCGGAAAAATAACGGCCGTAATTGGTTTTTTTCCCAATATTACAGCCCTTCCAGAATTACATATCGTCACCAACTAGGAATACAAAATCGAGCCAGATTCCCAAGCGCTCCCATATCTTTATGGTGCATTGATATAGCCAAACCCTGGTAGAGAAAGGGTGGGCGTACATCGTCAACTCTTCTGAGTAAAGTCTCAATTGAAGTGTCTTACAAAACGATCCGATATCGACTAGCTGTCTCTGTTCCTTCGGTGCCCAATAGACATTGACAAGCTGTGAAATGTTGGTTGCACTAACTTTGGGAAGCTGCTACAAATGGCATAACGATTACGACCGACGGGCTCTATTCCCTTTTGCCCCATCCTACTCTGTTATCTCGCAAATCCCAGATGTGCGACCTCCTAAACAGACAGAGTGGTGTTCCCGCGATCTGCTAGAAGCAGAGTGGTCTGGGTACGACGTACCTTCCTCGCGGAAAGTTAACGGGAGGGTTACCCTCCTGATTAAGCTCCGCGCCCTCCATCACGACTCCGATGGCCCGTTCAAACGACCCACTCGATATAACAGGACTAAGCCACCGCGCAGGGACCGCTTGACCTATCGCCAGCCCGTTGCTGGGGGAGCCTTGCTTTGCAAAATTAAGCCCCGAACCGGACATTTGCGGTCATTGCAAGGGCAGATCTACTCGTAAAGTTTCCCAGTATCGAATAGCTACGAGTAAACGGAAGCATAAACGCATCAGTTATTCCGGGAAGCTCTCTTTAACGTTGCTATCTCGGTATTAAACTCATTTTTGCCTCCGTCACTTGACCCCACCGGAGACAAAAGGAAGCGCGCTCTAGGCGAGGTATCTACTCGTAACCGCATCCACCCGAGCGTGGGTATTTGGCCTTGGTAAGGAATCTATCGATCATCTGACACGCTACTCCGGCTCTAAATAGCTTCGTTACGGGGACTATTCACAAATCACTGGAACCCATCTTTGTAAAATTGGGGGGCTGGGGCCATACTCAGTAACTAGGCGGTTTCGTTATCCACAGTAAGCTAGCTTGCCCCTTCAGTACAAGATTCAGCACTCTATGTCTCATTGCGGGTGCGGTCCTGAATGACTGTATTTCTCCAAAAGTCCTCTGAAGCGTCATCATCGTCAAGCTCCTTATCCTCTCTAATTGTCAATATTCAGATGTTGCGTCCATCGGAGCTCGGTATGGCGTGATAATACCAGAAACGTGTTAAATGAATGCTGACGGAAGCCGTTCGACCATTCCCCGAGAGTGCATGGTCGTGTGGCGACAGATCCTTCATTTACGCTACACTTTTGGCGGTTAGACCTCACCTTCCAGGTGTGTCGTGCGCATCATTCGGCGCAAATGACAGGTTTTGCCGACTTGACGCCCTATCCGTGGCACCCCCCTACCTTCGTGAGCGTTGGCCCTGCGGCACTTCCCCAAACCCTGTACATCGTGGGAGATCAGAGACACTCATAAGTACTAGCGTTGGAAGAACCGGTGTTGGCGGGTGTCAGCTCTCTCTGTATCACATACTCTGAAGTCCTACCAAGAGGGACGCTGCCTACGCTACGCCCAGGTAAAGGCATTGGACTGCTTGTTTTGTTCGGCGTCGCCCATTCACTACATCGTACCCAACGGTCTAAATTGTTGGACCAATTTGTTCCACGGATGGGCGAGCTGCATCACCTCACAGCGGAACCCCTTCATAATTCGCGACCTTCCCGCAAGGTGAGGTATAAGGAAAAAACGGCATCCCGTGCAGTCGCGGACCGCCACTGGACAGGTTCTGAGTACTAGATGGGTGTGGCCGAGAAGATCCGGACTAAAAGTCGCCTCAATCATCCGTTACCAGTTTCTAAGTGTATACGTGAGCGACACATTAGCTCTGGGTTTCACCACCAGTCGAATGCGTCAATTCAAAATTGGCGTCCTCGAACACGCTTTACGAGCGATGCTCATCGCGACACTCCAGTCACTGTTAAAGGTGTTCCGTTAAGGCAAGAGCAGCTCCACATATAACGTCCATGACATGTTGCAAGCCTGCACCATACGTCCTTTTGGAGCCGTAACCTTTTCCGGAAAGAGGATTCAGGTCAGCATTTTAGGTCTCTATTAGTGACATTGCGGATTCGCTCCGTTAACTCAAGGCCATCATTTTGGGCACTCCTCGGAGGGACCTAATTTTACTCCTACTTGCGCGATATCGATTGACAAAAGGAATTGCGTCGTATTTTCCATTGATATAAAGTGTACTTACGGCCCTGACATATCCTCACGGACACGCCAACACCACCCCGCCGTTCACGTGCCCCCCCTCGGGCTACCAACTGCACAAGGGCACCACAGCTTGACATCCATCAGCATGTTTTTTCGACTATTCGGCCGGCACCAAGTTGACACCGCCGACTGACGCGTGGTCAGCCGATCAGAGGCACCAAAACGGGGTCGCATGCCTTAGACGAATAAGGGTGCCATCGATGTTGGGTATTATTACCGAAACATTCGGATTAATAGTTGAAATAAACCTCCTATTCCAGAGTACTTACCCTAGACCTCAAATAAGACCTGCGAGTGGATGGTCTTAACAATCGGGTGGTCGTGGTCCCGGTTTGGGATAGCGAAGGATAGGGCAAGAGGACGTCCAAGTCCAGTAAACTCCAAACAGCACGCTCACTCTAACAGGGCGGTGATAATGGGGTAGTTAGACGAGCACTCATCGAGCAGTACTTGCAACTGTCTTTCTCCAAGCGACGCTTGTCCCAATGGCATCCGTAGACGACGATGTGTCGGTCCGCCGTCAGGGGAATTATTCGTATGATGCCTCGAGTCGGTCTCGGGAACTTTTCTCGGTTTCCGGTTCCTAGGGTTGCATCCCTAGGTCCAATAATCATCTGTCGTGAAGGGGCGAGTCCTTCGGGGAGATGCTAATTTCTATTGGCCCCAACCAATTTTATGAAGTGTCGGGCGGCGATGTAGTAAAATTTATTTCTATACCATGAAGAGTGCTCAAAGACTGATCCAGGTTCTGTCAAGCTTTTTCTACTATCTATGAGACCCTAGCCCACTATGCACTGGATACGATAACGATGCTAAGGACTACGATGATGCGTGCGGGTATTTACGCTTTGTTGGTTACCATAACACCCACAACGGATCTCTTATGGTTCTTTGATACTTTAAGATCCTTACAATATATCAGACATGTCTACAAGCCCATTCGGTGAATTCTTTTCTCTCTGAAGAGGGTTTTGGCGTTCAACCGGGTATGCTGAAAAGCGACTAAAGTTAGCGCGAGAAACATTATAACACAAGCTCGCTGTCTTAGCAGGTCGGGCTATGCCCAGGAGGGGAACGATGATGGACACGTGTACTTGTGCGACCGGTCATGGACATATCTCTCCGTTGGAGCGTCCGTTCCCAAATGGAGAGAGACTGTGACAGTTATCTACAACTGCCGGTAGCCGTGCCCACTCCTACGGTACCGCTAGTCACAGGGATAGCAGGAAGTTAGTCCCAGTTAGCCATCACGCGGAAGTTATTGACCGTCTGAGTTATTGTTCCCATTATGAGCCTAGCTGAGATGAGTCTCAGCGCGGCTCCGCCTGTTGATTAAAATGTTTCCAGATTAGGTACTTCCATGAACTGATTTGCTCATACATTGACGGCGGGCGAGATGACTACGCTTGCCGACTACGTGGGCTCGGCTCACAAGCTGCGCGGAGTGATCGAAATCAAGTCAGTTGCACATAGCCTCACCCAGCACCCTTGACCGGAGCAAAAGTGCTGAATGACTGCCCGCGCAACAGCTCATGTCTAACTATAGGTCCAAGGAGACAACTTGGAGAACGTTCCTGCGCAATGCTCCCAAGGTAGCCATGTGCCAGGTAAACGCCTGCTAATCTAGTTAAGGTTACACACTAGAGGGGTCCCATTATTGCTCACGTGGGCCACGTGCTACACTTCGCCCATAGCGTACGGTCTTTCACTAGTTCCGGGTACCCACATTACGTACGTTCGTTCACTACTCGCTCAGTAGCTAAGATCGGGCTCTGGGGAGTTCCAATAGAGCCAGGTCCGAGCCATCAATTGTCTGACATATTTTAACTCTAGAACTAAAGCAGCCCAGGTGGGAAGGCCACAAAGGAGCAGCCGGAGACTATCAGATAAATACATACGCACCACTAGTCGTCATAAATAAAGGAGTTGTCCCCATGCTACTTAGGATTCAACGGCTGGTAACGGGACGACAAATAGGATTACGGTTCTGTCTTAGTAAGGCTTATTCTATGGAATGGGGACGTTGGGCCTTCAAGAACGTAAGGGAATGTCAAGTCCGGCTTGGTTTTTTCCTGATAGGCGTGATACGCGAGCTTTTGAGTGTAATAGCGGGAGTGTCTGTTGTTAGATTACTTTTTCCGTAGTATCTCACTCAAACTAAATTAACACCAGTAGGTATTATACGCGGAATCTTCCGCTTTTGACGTAGAGCATCCCGTGTCCAAACCGAATTGTCCTTTTTGGATCGCATGACATAAGGTTAAGAATTTACCACCACTCGTAGGGAAAGACCAAAGCGGGACAGACAACTGCCAGCGGGGCATAGCCTACTTCCTGTTATATCAAGCTCCAGCTGACTCAGAACCAGAGTCAGTAACGCCTATCTCTGACCTTTGGGTACTCCCACGCGGTATCATTGGCGACCAGCTTGTGGAGGATCCATTTAGCCACTCAACTTGTTTCTAGTAGAATTGAATAGACACTGGAGAGATGGCCAGCGACTGATCTTGTCATACACTTGTAGGTACTGTACCTAAGGTGGTTCAATCCTGGCTACGGGTAACAGTTGGTGAGGTGGGCCCTTCCTTGCGTTTGATGGGGGCAGCCTCGTTGGGACCGACTACCTAACCAGGTATGGTTTCCTCGCAAAGCATGGGCCGCCAGTATCAACTTGAATTCCCGGATTACGTAGCAGATTACTCCTGTAGTTCTTACACGCCCTCCTCTAGAGAGGAGCCGCCACATAGGGTACGCTCGTCCTGGGGATATTCACTATACGACTGTGTACTCCCTGGCACTGCGCAATAACCGGAAATAGGAACATGATAGCAAATCACAGGCATTGACCCCAGTGAACAATACCAACCTCAGAAAATGGGGGAACACCCTGCACCTCCGTGCTGCCTATAATACCTCATATCGTCGGCTCTCCATATGAGGGATAAAGATTCTTGTGCTTCGAATTTCAGACAGTCGACCAGTAGAGCAGAATAATAATCGTCGACCTGGTCAGTAAGGGGGCCGGCTAACGTAGACGTTCCCTCACGACCGCTCAACGTGTCTAGACAAGCACACAGCATATTCCGTCCGGATCCACCAGTGTATATTGGTAAGTTGCTCCCAACTGGTCAGGATGATCCTCGAAATTATTTTGGATAAATAGATACAATGCCTATCCACCCAGGTAACACCACTGGTACGCTATTTAACGCCTTCTCCCGGGTCGCTTAACTAAGTATGCTACACCCACATGCTTCAAATATGGTCGTTTCACCCTGTCGGTAGACTCGTCAGACCTTGTCTCATACCCAGTGATTTCAACCGACCAGTGGTGATATAGTAGACCCTGGCGGTAACGATGTATCCTTATTGACTCACCTCAACCCCCTGTTCACACACATTACGCCCCGTCCGGGGCGAGTAGTGCTGCCAGGATTTTGGGGATACAAAAGGTCTCTTCCTTAGCGGTGTAGGGGCGGATTTACCTGTTTCTCAGGTTAGAGTCACATAAGCTCTGAGATAGATATGAGGGCGTCATAGGTTCGCACCGGACATACCTCGCATGTCCCCCTGGCGTAGCCACAAGGTGACTAGAGCCCACCCTGTCCGCGACCTTATGGCCCACATCTCGCTACTCACACCATTGATGTAATAGGGGAGTTATCCTTCGTTCAAGTCCGTTACCAGGTTCATCAAACAAGCTTTACGGATTGAAGCATCCCGGTAAAGACAGTAGCATGACTCCAAGGGCATTTTATAGCCTTAAAGGGCGTCCATGCGGGCCGGCAAGCCACTAAACCTTCATCTCGGACTGTTGGTCCTCTTTGCAAATTCATGAATGCTTTATGCTGGGAGACTAAGAACTTTTGAGGTTTCTATAGTTCAGCGGTGCGACGAAGTGGTCAGGCGCTGTAAATGAATGGAATACTCCTAGCGGGTTACCCCAGGCTTGAGGTTTTCCTAATAAACCCACAGCGTGGATCTCACCCAAGGCGCTAAGCCATAAATCAAGTCCCTAAATGTCCTTTTTAGAGCAAATGATCAGATCTCTGCGCGAAATTTGATCAATGTAGGACCGCAAAACCGCGAAGTCCCGCTGCAATCAAAAGGCGTTATACCGCCACCATTCCCGTGTGCAAATATATAGGCGACACCGCTGCAAAGCTCGGCTCATGCGATCATAACCCCACGCATAGCTTCCTCAATGTTATTTGCACTTCCCCCATCACACTGATATGCCCGGATGAACACCATTCGGGGTTTAATAGCCAGAAGATCCGCCTGCCTAAGATAGATTGTGGTTTCACCGAAGTAATGCCAAGCCAGTAGGTGACAAGACTGTTATCCATTCACGGGTGTAATATTTGGCGGTTCTCCTACAGGGTCGTTCCATGTGCAATGGGCCCTCTTACGACCCCGAGCAGCCTGAAGTCTGTCGAATTAATCTTATTCCTCAGCCCGCGGTCAGGAGGGCCGTAGGTCATACAATCAAGTGAACTCTGGCAGCGTGACGGCAGAAATGCGTAAGAACAGGGCTGTAACGATCCATGCCGGGTCAAGAGAAGGCAAACGGGGCTCTAACGTCCGATCTCGACGAAAATCGGAGGAACCGTCGCTAAATCGCTGTGCGCATTATTTACTCGGCTCTCTCTTGCCCATAAGTTTCTAGGTACGTACGCACCAATAGACAGGGGTATGTACTTTCGGGTAAGCACTGATCGTGGTGTTGTCAATCGGCTTCACTAGTGCTAGTGCTGAGAGTTCACTGTCCTTCTTCCGTGCTAGTTAATGAACCGCTTTCTATCCGGAGCGGTCTTCTTTCGCTCACTTGTAACATGCGCTAGTGGCACTACCGACAAGCAAAGCTAAGGTGCCTCCTCATCGACCGGAGGTCCCTCCGAGTTTAGACGAGCTTTGTTCACTCAAAACGAACACGCTGCGCATAGAGCAGGAATCAGTAAAGGGAACAACCTAACTGCAAACACGTGGCGGCTTGTCGTGTCTGACTACCGGGCAGTTCGGGTCCTAGGCGGTTAGTGAGCGGAACGCGTCGCCGGGCGTATCCGTAAGGATTGAAATAATTCTCTAAACGCCCCGCGTCGAATCTATGTCCCTTAGGCTGTGCCCGTCATTTCCGAAGCGCCCACAGGTAAGAAAAGATGGGTTTTGCAAGGCAAGGTTGCCGATTGGCGTTCGCAGCTGTTTAACAGCACATGCCGCGTGCTATACGGCAAGGAGAGCCTCTACTCATGACCGTCATCACACGCCATATGCCGTGAACCCCCCCGAGGAGTAAAGCGATGTTCTGCTGTACTTACTTCACAATTGTTAGCCGTGGAATTCGCATTCATTCCAACCGTTTCAATGATTCGAGCAGGCGAGGCTCCTGGGTGTTTCGTAGCAGGGCCCAACCACGAACATCTCCTTAAGCATCCACCCACGTGTAGTATGCACACCATAGATGGCATATGATTGTTCGAATGCTACCGTGATGCGCCTGTCTGACCAAATACCCTGAAGTTGCGGGCGCTTGTCCAAAATATGTAGGCGGGACACAGGGCCAACGTATTCCCTACGTCCGTGTACCTAGCTCAGGGCAAGTTTCTTCAGATTCCATTGGGACCCTGTAATAAGCAGCTTTTAAATTACGCTCCCTTCAACGAGACGGAAGCGATTCCGAAGCACCGAACCCTCAGAAATGGACATAGCTGGTGTTGTGGTGAAGCCTGAAATCCGACTCGGTACTATTTGTCATGGGGCTCCGGATATTTGTTGATCTTCGCTGCATTTGCGTCAAACTACGACACAAGTAGGATGGGCGTACCGCGAATTCATGACATGCGCCCCGACTATCATGAGCCAGAATGTAGAATCCAGGCAGTACCATTGGGAATGATTCCGTTGATTTGCAGACGGCGCATTCACTCTAAAGACACATATTGCAAGATTAACCTTCACTTTAACTCATGTCTCATACGGGTTGTACCAGCTGCTAACAACTTGACGTGGATGGCCGGGAAAAGACAGTAGTGGGTAAGAGGCATCTATCAGCGATACCACTTTGAATATGAATTATCCTATTAGAACCGTTCGCGTCGGCTTCTTAAAGTTAAAGGTCAAGAAGCGCCGGCCATCGTTAGGGCACATAGTGGCTATGAGTTGCGAACGTCATAAAACTCGTATTTAGCGAGGTCTCGGGACAGGATAGGGTTGCTGCGTAATTGTACGCGGCAGACAGTACAAACGTGCGCGCGGCGACTCCTATCTCTCCCGCTTAAGCTTTATATCAGCCTGCGCCGGGTGTGCGCGCGAAGCGAGTCTGAGTCCCGGTCGCTAGTGATAAGAAGGCACGTGCTCCCGAATTGCCCCCCTCTAAGGTGTGGTCCTGACGAGACTTTGGATCACGCCTCTGCACAACCAGGGGTTAGCAAGAAAAGCCCAACCTCCTTGACGGCCGTTCGCCCAATTGTAATGTCCGATATTAGGCGAGCTCAAAGTTATCGGGTGCTAAAGCTTCCACTTATCTTTAGAGGGCGCACAGTTGAGGTACGGGCCCGAGAATCGGTTCTGCCACGTAGACTCTTATGTGGTGTCGTATGTGGCGTAGTTCAACCGCGTCACGACGAATCGTCATAAAGGGTAAACTATCCCTAAGGGTTTTGGAATCTTGCGCAATAGTCGCCTTTGAACGGAAGAAGCCTTACCCCTCTGCGTTCACAGGGTAGCACAAGCTGCGACGAGAGTTACTGGTTGTTTGAGGGGTGCCCTAGTAGGACCTCCGCCGTATTATGTACTATCATCCGAGTGGGCCACCGCGCCCGCCTTAAACACATGCTACCAGTCTGTGCGAGTTGCAGGTGGATCGGCAAGGGGGGGTCCGCTACGCATGTAACCATAGGGGAGGGGTAGCAAAGGTGCGAGGACCACATGCCGGCGTAAAAACGAACTCTCACATGTCAGGCTTTGCATTCTGCGCCCCATAATCATCTAGGCTTTGCCCCACCGTAGCGAAACAGTTAATGCTTTGTCGCTCGTGGCTTAACTTCCTACGCGTTCTAGTTGCTACCCGAAGCGGCGTGTGGAGTCTGCGTTTTTAAGACCGGTGTAGTTCGCATGCAGACGTGAGACCCGAGTTGTGCTTGTGCCTTGTGGTACAACTCCACATATAGTCGCAGTGCGCACGCAAGGCGCACTTCGTCGCTGGCCGGGTCGGGTCGTACGTGCGTTACGAAGCAAAGAGTTGTTTATTAGAACGCTGTGATCCGCACGTAAGACCCGTTACTAGCTGCTCCTCTGTTCTTGCAAGGAGTGGTCAGCACGTATACCAGAACAATATCCTGTTAGAACTGTTAGACATACGACACTTCTCCACCTGGGATACGTAGGAAGGTGCCCCCTCACAACTGATGTCTTCCGCATCGCAAGACAACGTTGCAAAATATTACCCAGCGCCGCGCGTAGTGTGCACGTGCTGGTCCCTCGCAGTACCGACGGTAGATTTAACTCCTAAGTCGTTAAAAAAATTGTGATTCTACGAGGAGAGGCCTACGGGTTCTTTCACCAATTCGATAACTTTCCGACCGTCATATTCCCAATGAATGGAATTGAACTGGACAACATATTACTGACATAGAATCATGCGAGTGATCAAGAGTTCAGGAGTAACAGGTGATAACCTCGGTCGTGGGCCCGCGATTAAACAGACCTTAATGCACTGGATCAACGTTATAACTTCTCTGTAATTGGACATATCTTGTATCCTACCCAGACACTGAGGCACGCGGCTGGCAAGCCCCCAGGACAAGTTCATGCTGCGATGGGCTTTATTCGGACTGCCGGGCCTGACCAAGGCCGATCTATGAGTAGGGCGCGGTAAGAGCGAGCCCCGTTGTCCCAGCCGTGCTGAGGGCCATCTGCCTGGTAAGATACACAAGAAATACGCCTAAATGTTCGAAGAAGGCCTTAGATGATGAAACGTTCTAAACATGCGCGCTAACAGGCCACACTGTATGACATTGCCAGTCTCAATGGGGGATACACTTGAATTAGCCAATGTCTTGCCTCGCCTGACACCACTCGACTTCGCTGCACGGAGCAGCGCTTTTCCTTCAGTAAGCCTATAAGGGGATCTCTCTAGTCACGAACTGCGGTTTAACCCGAGAAGACGTTCCTAGTGAGAGCGCGAGCTCCGAGTACGTTCGGCTAGACTCCGTGAATGGGAGACTTAGGAACTAAGCAGCGCGGGGTTTCGTTTATTGGTACTTGTGCTTGAGCGGACGGGAGCACTTCCTGAGGCACATGCCGGGCGGGGTCGCAGGTAGGCTTAGCAGAGACCAGTAGCTCGTCCGCCTTTCCTCCCGAGCGTGAAAGCGGTAGCCATACACGGGGCTAATAGGGAGCGCACCATGCCCACAGTAGGCCAGCCCGGGCCTCACTCCCCCCATTTTCAGGCTACCTGCAGAGCCATTCGGGTTCCGTGGCGTTTCAGAGAGACCTGACTATCGGTTTGTGTCAGCCGATAGTCTTGCGATGTAACACACGAAGGGATAAAAAAGCGGCCGCAGTGTAGTACCAGAGGTATTTAAACGTTAGACCGAAATTGAGTTTTCGAGCCTATCGAATAATTTCGCTAGGGCTAGGTGATCCATTGGTTGAATTTGCACGCTTGCAAATACAGGCAGTGTGTCATCCAGCTCGCCATAAATGTTCAGGCGACTGACAAGAATTCGAAACTCACACGCACTAGTATTAAGCTTGGGTCACCCTGAGGCACGGGCGATTGTTCCGGGATTGATATCGGACGCCGCTTTTTAAACGATGTACAATTATCATATTTAGCCCATAGGCTCGATCATTCAGCCTTATGCGAACCTCGAAGGCAGGCGGAGTTAGTCGCAGTCCTCAAGGTGCCTCGTAACAAATAATGGGCAGCGCCTGACAAGGGTTGATGTACACTCTCACAACACTCTTAATTCAAAGGAGCCCGCTTATGGATAAAACTAATCCCAGCATTATCTCTCTAGGCTTTTTTTGGGAAGCTTAATCTCACACCTTAATTCCTCGTTCGCGGCCCCGTTGACAAACCTCGACGCCCAGCCTTATAGGAACATTAGATACTCGAAATATGGCAGCGAGAAAGTCCGAAGTGGCTACAAAATGACAATTGTCTACATCGGGAGTATTGCCTCGGTCTTTGGTTGATTGGAACGGGGTTGCATAAAGTACGCGTACATATCGTTGCCGGATAGATAATCTCAGTATTATTCTATTTCATGTGTGTGTAACGGCTACTCCGAAGTCCTGTCAATCAAGACGGGGGCAAGCACAACAGTTCACTCACGGATAGCAGATTATTTACGGCTGAGTTCAATATCGGCAGGAGGAATTAATTTGAACGAAAATACACGCCCCCGGGCTACTGTTTAGCAAGACTATCATACGCAAATACTATGCCATTGCTCGGTGGAATTTCGTTTCCGGACCATGATAAACCGTGTTGTTATTCCAAAAGCGAAAATTTTGATTTAGATCGGACCCTAGCATCCAATGCAGGATCTAAAATAATAATGCGGATAAAATGATAAATTCCCTGCGATCGACGGACGCTAAGTATTGAAGAGCATATAAGAATTGAACGGGTGGCTCCTTCGGTTATGTGGCACTGTTTGCTTGCCTGGCAGAGTATATCAACAGTGATCAACGCGGGAAACTCGGCCGCGGTCCGATGCTGTCTGCTTGGTTACCTCCGGTTTACCATCTGGTTCTACGTCCACTTCGTGCATTTTTGTTGGGTAGGCGCACCTGATGAATTGAGCTGCCCCCGATTTCGCACGTCTGACATCCGAATTTTTTGTCTCAACTTGTCAATTCCGGATCGTCCTAGCTCAGAACCCACGGATCAGCTCGGATAATTTGTTTGGTTGTTTTTACACGTTTATCATACGAGCACAATGGATGGGGCTCATACCCCGGCCCTGCCGGCGTGTGACGAGTGGAGATATTCCTTCTCTAGCTGTTCCTTGTGTAGGAGCACGCTTGGTCCTAACCGTAGCCACTTCGCGATATTGAATGGTTATGTTGCAGCTACAACCAGAACTGGTTGAGGGAGCCCCGAGCCTCGATCGTCTTCACGTCCATACGCATTCGCCACCCTAGCTGGGCTTAGACGTTAAACTGCGACCGGGTAATTACCTAATTCAGTCAAGCGTCCCGTTCCACATTAATATTCCAGATTTGCTTAATGGCCCAGTTAAATCTATCATTACGTAATAGCTGTTACTCCCTAAAGCGCCAAACTTTTGACCCCTTGTTACTTACAAATAAACGGGTTGCGTCTTTCTTTCCACGGACCTCCATGCTCGAATATTGTCTCTTTCCGTATTGTACTGTACAACTCGGTGACAGTTCGTAACTACCTTCAATAGCAACCAACCCCTGTTACACCCGTCGGGCTACTAGTTTCTCTTTACAGCCAGCGTCTGCAGGTAGCTCAGCCCTCAGATTCAGACACAATATGAGGCTCAACTTTGCACTGAGTCCGTGGCCGGAGGGCTCTGGCTAACGGTTACGTTAGCATGAAGTACTGGCTTCATAGAGCCGGGCCTAGTCACACTGGTTGGACACTACCCGGATAGAACGCAAGTTATAAGATATAGGGCAGGTTCTGGGGTGTGCCTGGATATTTTTTGTCCCAGGTTCCTTGCGGCATTGCGTTCAAGGTCTCTCTTACCCAGTCGTCATATACAAGATAATACTATCGACAATCTTGACAACGTCTGTTGAGAGCTCGCGTCATAGGGACGGCAGCGCTAGGGAGGTATGCCCAACCGGGAATGTGGGGTTCTCCACACCGTATGTCCGATGGGCACAACTAGACCGTGTCATTATAAGAAGCTACAACCGAGATGCCGCACCTCTTTAATGTTGATCCTGTATTGTGAACTATCACTCAGCTAATTCGGGGCCATAGGATATAGGCTTCTAAGTCGACTTTTCCGATGAAAGATCACTATCCAGCGTGTCAAGGGTAAATGACATCAGGACGCTGACAATTTGGCTGAATCCTTGGCGACGCGGCAAGAATAAAGGCATAGCACGGGCGTTTGAGGGGACGCTGATTGGCTCGGGTCCAGGTCTGACCTCCACGGAGTCCGGATTCGAACTCGGTCAGTCACACGGGAGGCTTAGGAGCCTTCGAACGGACGATAATATCCCGTTACTCGCCACTGTGCCTGCCTATAATGGAAAAGACAACTTTTTGGAAGGAGCTCGCATTGTCCGCGGCCGAGCGATTTCATGTGGCTTTGTGAAAGAACTCGAGTTGGACATAATGTCTGTATATGTATCGCCGACGCGACATATCCTGTACGTGTTGTCGATGATATGAAATTGACCTACTTACATGATACCAAAAGGAGGCGGCCCCCGGAAGGTTGGCCCGAAACACGAGCTCCTCGCAAATGATGTCATGACGATGGCAGAAGCCGAGCTCACGTCTCATTCGGTCGCAAATCCTTGATTCGTGCCGTAAGGAACTTGGGAGGGTAATAGCAGGTGCCACGTTCTCCTATTGTCGGACGCAGTGCTTATGTAACTGATTCCCTGAAACGTAAGCTATTTCGTCCGGAGATAGAACATTATGTCCACAAGGCAAGATATGTTTCCTATGAGAAGAAAACGACGCTTAATGACTTGGTGTTCTTTCTCCAGGCAAGATACGCGAGCGCCTACGGAACAAATGACGTCGTCTACGACGTCCAGATCCCAGCTTTTCGTTCGCTGCGGCCCCCAACTTTGCCAGTAGTGCCGATTGTGCGTTGCGGCAGGGGTCCTTCATACTAGTGCTTCATGCATTTGCCAGGTACCATGGATCTGCACTACTATCAACCGGGGACCGCGCCATCGCTTATGGGGTAGATGATCGCGCCACATCGTTAAGCGCGGATTATCGGAAGCAATCGTCCCACGTATCCTAGGTATAAGATATAAGTTGCAACCGCCACTAATCCCTCACACTTTCCACGGTGGAATCAGATGTCAAGCACTACAAACTTGGTCCACAGATGGGCAAATATATGTGCTCATCTCATAAAAGGTGTGACCGCTCGTTCCGGAACCTCAACTTTTGCTCGTAGCGGGTATTCCTGACGCGATTCACCAATCGGGGCCAACGGCTGACTTAGACCCGGCAAATAACACAGTCCAGCGTAGCTTGCGCATTTACGGCTTTTTGAGCTGGCGTTCCCGCCAGATTTGCACAATAACATCGATGAACCTGTGCTGCGGCTAAATGATAACGGAATGGACAGTTCGCAGTGCTTCTGATTGAGTTCGTGACCAAAGTCATCCGTAGGCAGGGCACTCTATACCTCACGTATGTAGCCTGTGTATCCTTGCCCAAAGGCGCGCGCAGCTCGAGGAGGCGGGATTGACCGGGACACATGTATTCGCCTCCGAGCGAACGCAGTAAATATTCATACGCAACGAAAGAGCTTCTTACGGTATTAACAATTTCATCCGGGGGTTATCGAGGATCCGCGCCACGGGTCTGCGCGAGACTCACGTGGCGGCGGATGAACCCGGCAACAGTCGGTGCCCCTGCTCAGCAGAGCGTTATTGCGAAGTCCATGAAAACCTTATTCACTAACCCGGAACAGCCCCTTTAATACCAAGTGTGAGTAGAATATTCACGCATGGGCAGGGTGTGGCGAAGAGGCGGCCACACATCGACCGGAAATCTCTGTCCTGCGTTCCATACCCCGACGAATTTCATTTCCCCACGGACTAACTTTCAGGGGGAATAAGCGAGGTACCCCTGGCAGAAAAGGCGCAATGTCTGATGAAATTTCTCGTGATGCTCGTGTGGACGATGGCAAAGCTCATGGAATTAGCTAGCAGCAGTGAAGTAAAAGCCGCTTCGGCGGCGACGGAGTGTATCACATCGGGTCGGATGTGGTCGCGGAGTGACGAGATCGAGGATGTGAGAGATAAGGCCCGTAGATCGGCAGGTGTGTGCCCTACGGCTCACTCGTGGTCAGCCAACTGAACTCGTGACCCTCGTTATGGATCTTAAGCTCTAGTAGGACAGCCCAACTACCACGTCTTAGAAGCCAACGATAAGCCCATAGGGCAATGTTTTTAAAGGAGCCCCCGTTCGTTTCGGCCACAATTAAGAATTGAGTTGATCATGAGGACTATGTGATTTAAAAAGTACACGAAAGGCGCTCAACGGAGTGTACTAGGCATTAATCATCCGAGTACATGCTATAGCTTGTCCAACACTGTGCGATGCGGCGAGCGCGGGTCTGAAACGCACCCGATATTGGTTATGTGTTGGGGTGCCCATCGCGCTGTGTCCCCGGTGGGAAAGTGATGTGCCATCATACAAACGATCGTAAATCTGCTGATAAGGACAGACGGAAGGCTAAAATGGAAAGATTGAGAATTGGGCGACTTTCTTTATTCTCAGAAGCAGGAATAGTCATCCGTAGTGCCGTCAGTTAGTAACAAATAGTTGCACGCTGCGGGGAAATCCCCCCACTCCCGGAGTACCCAGCAAGTTAGGAGGGTGAATCCCGGTTGGGCTCAGCGGACACATGGTGCCGACCAGTATTTCCGCATTTTACGGGACCCATACAACGCGTAACGCTTGACACTGGAAACAATAATAGATGTGTCATGAACTTCTAAAGGTCAGTTCTGTCGTCGATCAGTGCTCTCCGCGATACCCGAATGCGATTCTAAGAGTGCAGCTTTCCCTAATTTGCTACGCGACGTATAAATTGGCCTAGATTGATGGGTGGCGTAATGAAAAGTTATGCTGTTGGTTCGTATCCTGTGTATTTCGGTTCTTCAATTCGCACAGTGATTAACGGCCCATGACTGATGGACGTGGGCGTGTAGTATGGGTATACCCCCCTCAATCACCCCGAGTGCACCTTCGTGCGAGAAGCACATCGCCTACATGATTGGGTACCCCCTAGCTAATGACACCTCCGGCCGGTGCGGCGGAGTCGTAGAATGGGCCAATGATTCATCCCCTTGTTTCGTCAGTTCAGGTCCTGTGATGCACCGTACCTGCCTTATCATTCTCGAAGCCTGTTTAAGTTTCGTTTGCGAATTCTGCGGCCTGCTCTGATCCGGGGAGACCTTCGAACATGTGGTACCGAGACTGAGGTGAGTAGTTCAACCATTTAACTGGAACAGCTAAATGTCGCTTTCGCCCCTTACTTCTTGTATCTTTCGTGGCGTTACCATGAGGAGGGCATTTCTGACTGTCGCTTGGATGGAGGAGTAGAATAACCAGTACCCTATTCTGGCCCTGTCAGCGGCACCGGAAACCGGGCCGCACGTGTGTTCGCAGTCATTTGTTGACGAAGCATGCGTCCAGTGAAACGTATCAGGCATAACTTGCAGGGTAGGAAAATAGGCACTCGTAGCCTAGGTGCAAGGCGTTTTATGGCGCTAGAACTTAGAAACGAAAGATCCGGAGCTGTCCGATAACTAGTTTAAAGAATCACCATCGGGGGATTGCCAAACGATACTACCATTCCTTACACCAGTGAGGGGGCGCTTAGTGGGCATGGAGTTGACGCGGGATGCGCGGGCCAACAGATTCCAAAAAGTGACGCTATTTAAAGAGGTGGGCTATGGAATCGGCATGCTTACAGCTGCTCTTCCTCCTGTAGTAAGTATATGCGACCGATGGAGGTCAAAAGGTCTTGATTCGTCGGTGGCCGATGTTATGCGGTGAGATACCTCCCAACGGCGTTGATAAAGGAGGAGGCTTACCATTACGCCCATGTTCGAGCCCCCAGCCAGACATCGGTACCAAGAAGGGTAGTTGGATACACCCCGTTGCCACCAACGAGTGTCTTGTGATTGGCCGATTTCACCAAGGGCAGATCGACCTGGCGTGGAATTCCCTTATGCAACAGAGTCGACAGTTTGGGGTGTAACAATTGTGCGTAGGCCCAGCCGTCGAGTGGTCCAGGGCTGGTACTATACAGCTAGCCGTACAGAATACTCGAACATTGATCACCATGTGACACATCCGAATAAAGGCTAGCTACTTCCGCACAAGCAGATATATTGCCCCGAGTGGATTCCCTGGGGTCTCTGAGGTATGGGGATAACATACTTTTTAGGACTACAGATAAAAGTCTTACATGGAAACCAGCTACGCGTGGTAAACGGATAACGCCACCGGATGTTAATTGGCCTCGCGAGAAGTTTCATATGCACTTAGGGGTCTTAAGCCGTAGCGCTCGGTTTATGCGGCATTGCGAAGTCTGACGAGGCCATTCGACAAGTCCAACAACTTATCACACTTGGTTTGTGCTGGGCTGTGAAGTCTGCAATTGCAGGTAACTTAGCACTCCGTGATCTACACCCAACCGGCCGTACCTCTTGGGTAAAGAGACTGACCCGGGTGTGATATCTGTGGTAGCCAGGTGTTCATTCAAATAAAAATTGTCCTAGCATTCCGACTCTAATTTTCAAACCGTTGCAAAATTCATCGTTCTAAAAGCAATAGCTTGAGAGGTCCTTTTTTACGGGTCACTGCATCAATATTCTTTCCTCTACCACTCAGTTGATCTTAGTCACGGGTATAAAATATCCCTACTGTACTGTTTGCCGGGCGCGACGGTATATTACCCGTGGGGCGGCGCCATCCGATAGACTCGTATATATCAATCACTTCCGCGGAAATTTTCAGCGTGAGCCAATCGATTGACACAGAGTCCGGCACCGGGGTGACGCATTGAGGTCCATGACACTCGAAACTTGGGCTACGACAGGCGCGGGACGGCCGGCTCGTTACTGAACTGTCAATGGGGATCGCGTGCTTACGGTGCGCGAAGGATTTATTTGAACGAAGGCATCTTCTTAATTGTCTTCATTAAAATGGCCTGGTATATAGTTCGCTAGGCGTTTCTACAGTACGGGTAACTTTCTCTCAAGCAGGAACCGCAAACGTCGATGCTGCAGTGGCATTACGGGGTGATCTTAACATCAAGGAATATCTCCGGTGATTCGACACGTCTCCCCACTTAGCGCGTGACCTCTGACAGGTACCGACTGTAAAAGATCTACGTGTTATATTCAACATTATCCAGCAAGTCGTGGAGTGCGTACATGTTATTGTTTGTGTACTAGAACACTACTATGACGGGTGGAGCCATCATGGTTGACACGGAAGGATAAGGATTGCGCACCCATCAGGAACATGTACTAGACACTGCGCGTTACCACCATAAGCCAGTGCCAAGGATATTGGAACGCTAGGCTTACAGTAAGGCCACAAAGATGAGACTCCTAGATCGTCTGCCGTAATATAACAACTGTACTGCTACAACGACCGATATGCGCATGGCATGGATGCGTAGTTTTCAGGGCATTCGGTATACCGGAGCTGTGCCGAAATCACCGTTTCGGCCACGACGCTCACACGATGGTCTGTGAGACAGGGGGGCTCGCAATCTTCCCCATGAACATGGCGTGATTCAAGAGGAAGCGGTGGCGTGTTCGTAGGCGGGGCGCTTTTCATTTCACGAGAGTAAGACAATAGCAAAGTGACGGCCACGATAAGGGAACTAGAGAAACGAAATTATATTACACGTGCAGTCCGGATGGCCTTGCTGATGTAGCTACATGTCCCACTATTCGCGTTGCTACAGGGGGTCTAGGCGTCTGTCGGAGATTCTATTCAGAACATATGTACAACAATCGGCTAGGACCCACTGGCTAAACGCCTGTGGCAGAGTCTCGCTTTCTGTCAAGTCTACACTAGTAATAATGGTCGCGACTGTGTGCTTAAGCGATCCCGGGCGTATCCGATATGAGAGGTAAAGGTATATTGCTCGTCCCGCCCCCATCTAGGTGCGCGTTTTTCTAGATGATTCAGACCCTCTAAGCACCGACGATACTAGTACAAGAACTCTCCATGGTACCCTCATGCAGCTGTGACGTACCGTGTAAGTATCACTGTATAACTACGATTGGGTAATGCTCGTGTACCTGGTCTATAGTTTACGTATGGCACGTGCCAACCGCGCACCTTTTAGGATTCGAAAAGGCTGCGATCGCGGATGTGCTGGCTCGCTTCACAAAGAATAGGGCGCCGTATTAGCTCGCGGCCGGGTTGCGTTCCCGCTAAGTTACTCTATGCACGCTGGTATAAACTCTAGAGATATAAAATCATGAGCCCAGGGCGGGTTGTAAATATCAGCAACGTAACAATTGTGTGCGTTCCTTGGTATCTGCGCAATCGCGATTCTGGGTTACCGCGAGAGCCCCAGGTTCCGGTTTTACAAGTACAGGGCACAAGAGAGATACAGATGAGTGCACGCAAGATGCATTATCGCCATAACTGAAATGGAAGTTCCTTCCGCTAAAGTTGTACCGCACCGAGAGAAACCATTACTCCAAGGACGCTACAACGGGCTCATCTTCCCGTCAGCGGGTATGCAGTATACTTTACGCGGCCGTCCAACATCCCAGTCTATACCTAACCTTAGACATCGTCTTACAACAGCCGGTATCCCTGTGACCGCCCTACGTACGTTGTGGGTGGAAATCAAAAGACTAAATCAATGGATTTCGATGTCGGAGTGACTTTACTCCATGTGAATAAGACCGGACGAACGCCAACTCGAATTGTACCCGGCTCTCCTTTATCGACAGATGCGTCAATACACAGCGAGATCTATGCCTCGAGCAAATCCGGACACTTGACGTCTGCGATCGTAGAAGGACGGTTTTGTTAATCGTACAAACTACCTCCAATATAGCCCCTCGTACTGTTGACAGCGATACGGTGCTATGGCACTAATCTTCACTGGCGTTTATGGGTATGACAGCTTGGATCATTTACCCCTGACCACTCTTACATACGGAAGACAAATTCCAACCAAGCGCTGGATCTTCGCCAGTGACACCAGAATAGTAACCGGGACCACACATTCCTCAGCTGAAGGAAAAGGTAGCAAGTCACTGGAAGGCCTGGGCACAGGAACGATTGCCAAAATTCTTAAACGAGGCACGAGTAGTGATCCTAAGGCACGGAAACAGCGCGTGGCCGATCTGTCGTGCACCTTGTGGTACTTTTCTGGACGAAGAGCAACGTGTATTAACTCTTAACGCTCTTCTGACATGGCTCACAACGCAACAACGTACCGTTTAAGACTCACGGACACCTAACGCTTCCAACCCCCAAGTATTCACGATGCTCCCTCCGTCGTATACCACTCGTTAACTTGATAGGCTTGCTGAAAACAGTGCTCAGGCCCGGTCGGTCGCCTGTGGTAGCTACCTTACTTTACAGCGAATCTAGCGATAAGTTACGTTCAAACAAGACTGACTTTAACGCCGACGGAGAGTTAACCAATGGACCTTCCAGCGGCGCTGACTGTTAGGTGTGCAACTCCCCATGCCAATTAAAACCAATGGGCCTTACAAAATATGATCTGAATGTCCACATTAGTCTGGGAAGAGTCATATTGTGTCCATAGACCAACTTATCAATAGCCCCAGATACTCCCTTGCGGTATGGAGCTAGCATAGTTGCTTTAGTTATTTGAGAACGTGAACTTCCTATTTGTTGTTTACAATTCTAATCGTCTCCTATGCGAACACATAGAGTCCTGACCTAATTCGTTACGTGGCTTGGAAGGTTGCACAGGTCTATAAAGCCGTAGACAGTGGTCCAGATCGTCTTTGCGTTAATTCGGGACAAATCCCTTCCAGTTAACGTTACCACACGGGAGCTCCTACACGAAAATGCTCTTGGGTGTCCTATAACCTGTACATCTACCCAGGCTCGTCGCACCCCCAGGGAAAGGCCACATCTGCGAGGGCTCTGGCGGACCGTGAGTCTTTATTCTTACTCCAACTCCCCCGAAGTAGGCACTGAAGGCCGTTCGTGTGACAGTTCGACCCAGCAGCTCCGCCGTAAAATGCTACAGAATGAGTGACCCCCCCAGTACGGACACAATAGATTGTCCCTCGTCCACCGATATGCGACGCAATTATGCTCGAGCACAGTTTGCATACGATGCCTACAGATGGGTACCACTTGGGCCGGGGCGACTTTCGCCGGGATTGCCGAATATACGTAATGCCGTCATCGGGCCATTTAAAACGGGGAGACTGGGTGGGGAACAGTGAACCCTGAGGCTAGGCGCAAACATTGAGGGGATCGGACCGTTCAAGCCACGAATCCCACGGCGAAGATATCTAGGAACATGTAATCTGACGGATCTCTTACGAAAATCAGAGAACTGGTGCATCAGTGTCATGCCTTTTTAGACATCATATACATGTCTTAGCACATGGCAATTGGGTGCACAACATCCTTGAGTCGAATTCCCTACCGGTTAAGGGGACGTACAGAACACAACATAGGAAGTCTAGTTCGATGACGATCGAAAGCTCGTGCAACATTTACATTTCACGACGGACTCATTAACGTTGCCCCGGCGTGATATACGTCTGCCACTCGGCCCGTCGTACTAAGGTAATCCACTTGAAAGAGCAAGGTCTCTTGCAGGTGACAACACGTGCCTTTTCCGGTACTCAGGTGAATATATCTCGTCCAATGGGCCTCGCCGCAACTATCACCCTCGTTATCGACGCTAGGACGGTTGGGGATTTCTGCATTGGCTCGTAACTACCATATAAACTTTGCAAACCGGATTCCTTGCGTAGGGACCTTCATTGATATGGAAAGCTGCTCATCGTAGGGTATTTGCGCCGCGCAGTTTAAATGTCTTAATGCTGCGCCTCTAACGCTGTCATAAAACGTTTTTGTGAATAATAGAGACTAACTTCCGCTATTTCAAGTGAGTCTTGCTGGTCAGAAACAG GT 0/1 0/1 +20 860000 . A . PASS SVTYPE=INS;END=860000;SVLEN=1000 GT 0/1 0/1 +20 900000 . C CACCCGTTTATGAACTCAGCGCCGAACAGAAAAAATAGCCCCACTTTAAGTCCGCTTTAGCGACTCTAGGGTCCGAACGCGCTGTTTCGTACATGGCACGTCGGTAGGCAAGAACTCCCGTCCTCAGATGAAGATGCGTAATATCCTTACGTATTTTGGAACTCAGGCTGCCGAGCATCTTATTGGGAGACTCTTACCACTTTGCCCGTAAGCAGGGAAACGACATTTGATAAAGGATGGCAGGGAAGCTTTTATGCCCCTTTTCCTACTACAACGTCGAATGTTGACTTCCTGGTTAGCGTTGTGGCCTTGTACTGACCCTACTAGGGTTTCAGCTGCCTAGAGGACATTCGACCGACCCACGACCGCAGCTCGCGGTTCATACACGAGAAGCTACAATCCGCTTAAGTATTTGTTCTTTTCGTTCTAGGGCCCGCGGCACCAAGGAGGCTTCAGAAAGAGAATAATTACTCGATCGTCCCGTAAGTAGTGTATCGCTAACAGGGCCTGCGTCGTCCATACTAAGGCAAGGTGCTCCAGCAGGGCATAGGAATTGACCGGCGGGTAACATTGGAGACAACATGTGATTTGTTGCTTAATCTCGGTTAACCCGCCCCGCTGTAAAGGCGAGACGGCAATCATGAATTCTAGCACGCACCCCGCCCGTCTCTGTCTTCAAAATGTATTTTTGGCAACGAAGGATCAGCCTGTCCCGAATCGACACTGTGTTCCTATGGCGTAAAGAATTCTGTTCCTGAATCGCGGGCGCACCGTAATTCTTACTTTCACATCGAATTGTTAGATGCTGACGAGCAGAGCGCAGTGCGGCCGGGCGGAGATTGCAGGGCTGGCAGAGCCATTGGCCGTTGATGGTGTTTAGACGCTAAGCTAACCCTATGCCTCATGGATACTTGCTACACAACAGTGTCTGCGTAGGCTGAAATGGGGACGGCATGAGACCTCAGTGTCAACACAATTTGATGCACTGGGTTTTCTGCAACTACTTTACTACGGCTTTGTCCTTAACGCGTTAAGGGACTCCATCTCATCCGTATCATAAACTCCGTAGTGTATTGGGGCCAAATCTAGAATACGTACCGTCGACAATGCTCACGAGGGTTACTCAAAACTCGGCGGGGTGCCTCAATCCGCGTGCCGTGAAATGCCCGTATTCACGACGACTAAGCACTTAAGTCTCGGGAGCTCTGTTGCGTCTCGTCTAAGGGCAGTCTTGCTTCCTGTGTCTGCAAGTTCCTCTCTAGTGTTTAGGGTGCCTAATATACTCCACGTGTGTCTATGGACTCCATATGGTAAGTAATGGTGTTTGATAAACCCCTGGCCCTTTAGGTTCTACCTAGCCTAACTTCTTCCTTTGACTTTTACCCCCATTGATCCATGTTCGTCGAAGTGGCCGATTGAGGCTGCCGCATGGCCAAACCGCTAACCCGATCGAGAAGGTTGCAAGGGCGCATCCGCAAATAAACCATGGTTGCTAATTGGGGTGCAGGCGTAGAATTTGTCGGTTCAAAAGGCCCTCGACCTGCACAATGACTTGCGCTCGTAACTTATGATAGGGCCGGCATGGGATTATTCGAGGGACTCCTCACACTCAGAAGTTTACTCCCGGAGCACGACTTTACGAGGTGTGTTGCTTTATGATGGCATATAAAAAAGATGCACCAATCACCAAAACCCAACTATCCTTGACACGATCAGTGCGCGACCTACGACTACTCTAGTGGTACGACTATCGCGATGGAGGGGATATTCGTATATTTGAAGTTCATGTATTGATTCGGTTATGGCGTCTCCCTTAGTGTTTATGGACTTCATGCGTGCCCCTTATCCGCCCGCAGGCACCAATCACATTGTGGAGTTAGTTGGAGCGAAATTGGGTGGCTGTACGGTCAAACTAGAAGCATACCTTCACAAGGGCGTGGCGCTATGGGAAGTGGACCTGAGGGACACGATGGGTGAGATTCGGACACTCTGTCTACAAAATTAGGAGGTACCTACTGCTAGCGAGCTTCAAAATTCGGGAAGAGATCCTCGTACCACGTATTAATGAAGAGCCAGTGGAGCGAAGAAATTATCGCAAGACCGACCCTGTGCCGGCAGATGGACGTGTTAAACATGGTACATTGAGCAGTCCGACTCGTTGTATAGTTACCACGTGTGAGAAGACTTAGCTCGCAGCTAGTGGACAAGAACTCGGCCGAAGTTTCGTTCCTGTATTGCGCGTGTCCAGGATGTGAACAGTCCAACTTCATTATTTTATTCTGACTTGACACTGGACGTAAGTCAGCTGCTCAGAAACCGGAGTTCCCTGCCTTGGCCTGGGGGCCCCATTTGCGGATGAGCCCACAGGTCTCGTAGACTTAGGTGACGCCGGGATCTGCTGGCCTTATGTCCCTAGAAGCTTGGATGACCGGCCCACGGCAATGCGTAGTCAGGGAGGTATCCATGACGTGCGTGAGTCGGGCGAAGAGGGCCCCACATGCACCTAGAATAGCTATGTGTGTTTCTCGGGCGGAGCCCGACGTCGTCCCGCTCATATCCAAGTGCTTTTTCCGGGGGTTAAGCGGTGGCTTGGGCACAAACGGTCGCCTCCGCCCGCTTGGTCTCTCAGGTATTTCCGGGGGCACTCATAAACTACGAACGCGATCTCCGATAGCCTTCAGTTGTGGGGATGCGGCTAAATCCAAGCAATTGCGACGCTTTGGGTGTGGTGGGGGTTACTGATCCGGACTGCAAATTACTAACTCCGTCACCTATCAACACGTCTCCCTAATCTGTTGGAACCTCGCTCTATGACATCAGAATGCGAGCGCGGACATGGGACATGTCGGGACAATCTATTCTGCCTCTCCGGTACTGGGTACGATAAGCGCGACACAAGATTGTGCTCTTACTTCGCCGTGTTACCGGGTAAATCGCCGGGATGCTACTCTTATATGTGCCTTCTCACCTGAAGCCTTGCGACCTCGAATGATTTGGGTGTGAGTAAGCACCCGGGATCGAAGCTGGTAAGCACGTCACCATGTTAGAGATACTTGACCGACGATGCCCTTCTACGGCTCGGTTCACGGTGCCCAGCGGGATCCTCTTATCCCAGCCGGTGCCTAGCCGATAAAAGCTCACAAGCTTAAGGCTCTGTCAGGGGAGATGTGGGAGAGGCTCGATGAGAAGTCCTAACGACACCAGAACCCCAATTAGCACACATGGCTCTTCCGGGGACTTGGCTCTCGTAACTGCCTGCAATGTACTACGTCGCATGCTCATGTACCAGACATTATGTCCGTCCTTAACAGTCGTATTGGAGCAAGTTGTGAGTACAAACAGTACACAAGCTGTAGGTCACTCCCCCCACGTCTACCCTATATACTATAAGTCCTTGTAGCCAGGATGAGTAGGCCCCGTGTACCTTATTTGAATGCGCACCCGTGACTTCTGGTGGAGAACTTGGTCACGTCGGGTGGACCGTGTACGATACCCCACAGTGCCCCAGGAGGTATGGAACGATGCTGCCCTGAAAGGTGGAAGGCCGGAGTTTTTGTAGTTACAAACAGTACTCAGCGCTATCAGCAAGTGGACACGGAGAAGTAATTGAATGACCGCCTAGCAGTGCTCCGCCTCCGGGCGGCAGCCCGCGTGCCTCAGTCAGAGATCTCGAGCACGCACCCTTGCTGCTTCCGACTAATGGGAAGAAGTGGAGATGGCGACCCCCACGCGTTATAGTCCCAAGGTTGCTTCCAGGAGCTATACCCGAACCTTTAGGTCTAGACTTGTCGAGTTTGCGACCGTACTCGCTTTGTATGTCGACTTTTTTGAAAAGACAACCGTGGCCCGGTCACTGTGTCTCCAGTTTGGCGAGCCGTAGTCAGTGATCGCGCTGCTCGGGATCAATTATCTCCAACGGTCAGCAGATCTACGGAGTCGGTGGCCGGTATAATGCTGGAGGCCGGTGTATGCAGGAACCTAATAGTCCCCGAGTGTCGATCTGTACGGGAGTCACTAAGATAAGGCAGAACTGACTATCTCTCCACCGCTACGTAGTCCAGTGCCAAGGTGTGGTCATGGCCCACATAAATCAAGGATTTGTATGCTAGAATTACGCGATCGAGTGACACTCAGAGTGCACTGGCTAAGGACTCTAGCTTTGTAAAGACAGCATTACATCAACACTCGTTGCATTCCTAGACTGCGGTTCCTTCGGGATCTCCCCTTGGTACTTCCTATATTTCCTGAGATGTGGGCGCAAACAAATGCCAGATCCCGCCTGTAGGCATTCGGGACGGGTACTACGCGATGACCATATCGAGATTGAATCTTACGTATCTCCCTACAAGTGTGGCTTAAGGGGTTAGCACCGACAACTCATATAAAAACCAAGTAAAGAGAGTAAACACAGTGCGGAGTAGCCGTACTTGCGAAGCGCCATTTGGGCGCGACCTTCCGAATTTGCATCCGACGTCGGTCGTATAGCAAAGAGCGATTCTGAGCCTCCAGTCGCGGCCACGTCGCCGCTTGGCCAATGTATACCAGTTGTGAATAGGTCGCGGAACGCTAATGGAAGTAACCCCTCCTATTACCAACACGCCTCAATCGTACCACCGGTACCCACGGCATATAGAGACTATACGGCGTCGCGGCGGGCCTCCTCATGCTCGTATGGACTACACACCATGTCCTAATAACCTTGGTAACATTACGCCTTTGAGGGGTTCTTTATCTCCGATTTCGCGGTAGATAAGGCCACATGACATTTTCCGTTCGAGCGGACACGTGTCGCCTCAGTAGCCTATTGCCGTCGCCCAACCTACGCCACTGGCTCATGCCATGCCATCTCATACAATTAACTCCCGACGTTCGTACCAGGTGTACCAGGGGGTCCATACTAAGAGAGTGTGACCTCCAGATTCTAAAATACTATGTGAGGAAGTCATGATTTCCTCTAGTCATTGTGGCACCGCTCGTACCGTGAATCATATCAGATAAGAACGATCAGTTTGCGACTGTTATTCCGAGGGTACAGTCTTTAAGACACCATTCGGAAACGAAAAGGGACTAATGGATGCCGCGAAAAACCTAAAAAGGAAACAAGCTATCGATCTGTGGCGCCAAGGAGGGCGGGGCCCCGCATGACTCGTCAACTCCCATAGGCACCGCTCCGGGCCGGTAGCGACCGGAAGGCAATTGCTACCCTATCATATAAATGATCCTGGTCATTAGTTGTGCCCCGTATACTTGAGTCAAGTATTCCGTCGCAGAGACTACTGCTCATCCGAGACAACTTCTTCTCTAAGCGACCCGGGCGGACAAATTCACACGCAGATGGGAATTACACTAGGGGTATACTCACCCGGGCCTAAGGAAGGCACATGAGTGGGGCGGGCTGATTAGCAATTGTATCAAACTAGGGTCAGGCACACATAATGAAGGAGCAAATACATTGCACGGATATAGCCTAGTCGAGTTCGACGCGGAAGAGGTAGGCGAAATAAACTGTGAAAATGGGCAACACCTCACGAATGGTCATGAGTCAATGTAAAATCTTCGCGGCTTACTCGGCCTATTGCTATCGTGACTCCCAGGCCCTCAGTCCACCTCTCGTCAGATACTAGTTCGGGAGGCTCGAGATAATTGACCCTCCCTAATTCAAACTCAAACGAACTCACGTACGGGTAGGGCACCTAATTCGAGATGAAACATGCCTAAACGCCTCGAGAATATGTCTGTTTTGTACATAGTCTGTCGCTTATTCCACCACTTCAATCTGAAAATAGCGGACTAGTCCCGAGGGCCCCGATTTGACAGGTGGTTGAGAAGATCAAGTTGCACGCTAGCACCAGACCCTAACTCGCAACTGCTCTGCCTGATAAAAAACACATGAATCTGCGAACCATAACCTTCTTTGCCATTCTTTGTCTGCGGTTAGCGATGGGGGGTGTAAAACCACCTGCAGCGCGTCCCGATGATAAGCTATATGGGTTCACGTGCAATCCCAGAATCCTTTGGGGGGTGGATCAAATTGAAGCGAACGCAGCGTTGTATCGACGGTGAGCCCGCACATTTGAACTCGTTCCTCGGGTTCTTCGATGAATGTGGACTACGCTAGTTGACAATGCCTGCAAGTCTCCTCTCTCCCCCACGTGTAATATTGTACATAGTCAAGAAAGCTACATGCACGCCGACGTATCTTCTGTGCTTATGGATCGTTATAAAATTTTGTACTTACAGTGAAAATATGAAGGATGAAGCCTTAGAACTCGCTGCGTGAGAGAGAAACCCACCTATAACAAGACGCACGTGGCGCACATCCGTCCCCAGTGTTCAGCGACAGTTTGTCTAGCCAGTGAATCGGATCAGGCGGTCCTAGAGGTCTAGGCGACTTATGATCTTAGTCAGTAACCCCAGTAATTACCGTGATTACCATTTACAACGGTTAATTGGGTTGGTCTATGGTAACGCACAAATTACTCGTCATACCTGCTTAACATGCCTTCGGGAGTTAACGCTGTCGGGCGGGGTCAGCTTACATTACAGTAATCCGGCAAAAGACAAACCAATGCATCTCAAGAACCAACATAATAAAAAGCCTTATCAAATCTGGATCACAACTAAACGTATCACAGTAATATGTATCGCGAGTCTAGGAACTTGAGCACCCAATCATCATCCGTGGCGTCTCCGCGGGCTCTGAACGAGAAAACTGGGCACTCCCGGCTACTTTGAAATCAGGAAAAGGTCATCTGTTAAATGTCTGTTCACGATAATAGGCTATTCCACTTCAATACATGAATGACTTAGGATAGATATTCCCCTGGGCACGATGTTCTTATGGAGTGCGGGATTTAGTGGATATTCACGCTTGTATTCAGTCCCCTGTCCCATCACCTTTTTATTTGTCCTCCGCCCGGATTCGTTTCGTGCACGGCCAACGAGGAGCTGTTCATCAAATCTACCGACATTAATAAGTCTGGCCTATATGTCGTCCAACTAGGGACCCCTTTCAGAGTAGGTGGAGCTATCGTAGTCATCAAGTCACAAAATGAGTTCCTTTAAGGTGGCGATGTGTTGGGTGCAGACAGTATAGATAACACTCGGCATGGCTTTAGTCCCTCTATCTCGGATGCGCGCATCACAGATACCGCACAGGGTCCCACCTTACATGTTCGGTTGGGACTGAGTGGAAAAGTTGGACCCTAATGGTTGCTTCCGCGAGAACAGAGACTTGAAGCAGTCAGTCAGGGATTCAGTCCGTCAGATAGGGGTGGAAGTATGGCCGGCGGCCATTTGAAGTCGGCTAGCAGCAAATAAATTGCGTAAATATGTTGGTGTTTGGGACAAGGAGGCACGGATCCAGACGTTACTGAGTCCCCGAAAGCGTTACTCACGGATACACGCCATACGCTCTACTAAGAAGAACCATGCACGGACCATTCGATACAGTCTTTCAAACGCCAATGAACCAGGAGCCGGGGGGATGAAGGTGGGTTGGAGGCATCGGAGTGGTTGGGAACTGGTAAACGAGAAGGCCTAAGAGTACTCCCAACGCGGTGGGTAGTATGTAGGTTGGTTTAAGTCGCGTTATCTGGAGCCCGATACAGAAGACCATCAGCTAAGAGTGGTCGTAAGACAACAGATAATCCAGGCATACTAACACCGTTTTATTAACACCTAACCCGTGCGCGGGCAATGATCTGTGATTTCGGCGGAACCCTTTAGCAATCACTCGAATGCTCCCCTCAAATTTGAAAGGCATGACCTCCGTTGTACGCCCTGGATTTCTTAGGGATCGATTAAATTGGAGGCGAATCGTGTGTCTGATCTATTGGCCAATTTGATAAATCGGGACAGAAAACCCTGGGCAGCTGTATCCCGGCCAACTTGACTTTCACCTTTATGCTATCAGAAAAATCGGTGAAACTGAAAGTCTCTGAAGTTCTCTGCAGTCATGCGGGTACACGAATGTGAATATGAGCTGTCGCGAGTTAATAGGACAGGCAGAAGCGCAGGTTGCGTCCTAACAGGAATACTCTTAAAGTAGGTGCGAATCGAGCAACGTCATCGCGTCAAGCGCGACCGCTTCAGTTGGTTGGAGGCTGTCGGCAGGTTCATCTTGCCAAATCGAACTAGCAGTGGCTTCGTTACGGGCCAATACCACCTCGAGGAACCCGGGTAATGAGGTACAGCTTACACAGGCAACCTGACAGAATGGATGTTTGACCTTCTATGCTGTACGTGTTAGCCCAACACAATTAGCAAGATTGCACCGGCGCTAACAATGTTAATGAGGTGTACTAAAGAGGTCGTACAGACAGGTCATGGGGGTAGGCGTATTTTCGCGCAGAACACGGGTCTATCCCATGAACGTACAGGCAAAATATTCGTTCTAGGAGCTGTGGGTCGGTTCCGTGGAGAAAAGTCGCAAGGCTATGTAAGCATTCATGCCTAATCCTCGCAAAAAGTGTGTGGGATTAGAAGCGTGTCTGAGCAGATGTGGTGCGGGATCGAAATAAGTAGGTAACTACCACAGCACACTATTCCAAGCAATAGTTCGAAAAAGGAAGACAAACCGATTCGGTTAAACTTGTGGCGGTCCTTTATTGCGCTAGCGTGCACATACTTATAACCGTTCCTTGCTAGATGCCAATACACGATATTGGCACATCAGGTGCTTTCACCCGAGACAAACGGCCTCTGCTAGCAATCCCGGGTCGGTAAAAATAGAAGACGAGAGGACGGCGATCATATCGTGCGAATAGTATCAGGCTTCATATGGGCAGTTCGCCTCGAGGACTACCCTCGTCGAAAAGCTTTACCGGAAGATGCCAAACCCGGGCAGCGGCACCAGGCTGTTACCCGTACTCCTAATAGCTCGGCTAAAACACGGAGAATGAAATACCTGTACCAAACGCACGTTGAGCTTCATCCACCTCTGGCGTGTGTACTATCCTATAGCGGATTTCGCCGGAGTTGCCTTTTCTCCTTGAGTGTTGATGCTGCCTTCTAACAAGCGCCTTTGCACCCAACATCGACATTTAAACTTTATTATGGGGTTGGTCCTGCTCCGTGCAACTGTCCTCTCTGTCACCACTATATTAAACATAGTCTGACCTAATGCAAGTTAGTAAGGAACAAGAGCAGCCTCATAAAGACTTGGCGACGCGTTGAGACACATATTGGGTACTTTAGGGATAATAAGTGTGAGGTACGAGGTGCGCGGACATTATCTTGATGCCCTTCTTGGAAATGTCGTATTTCAGGCCCCTGGTGCGGAAGAACTTTGGCCGGGTTTACATAGTTTAGATAGTCCTAGGTACATCAAGACGCCAGTATGAGTCCGCGAGCCGGTATGAGTCATATACAAGCCAAAGGGCCGCCTCCAACTTCTGTATCCGTAATTTTCTCCATAGGGCTCTGACCAGTATTGACCCCAAAATGTGGGCTGCAGATCCAAAGAGTTAACGGTACTACCCGAGGGATCAGTCATTCACTACGGTGCGCCTTGGATGGGATCCTACCGTTGAATTCGTAGCCTCCTGCGCTCCGCTAACCCTGACAATATGTGCACTTCGCCTGGACGTATTGACACCTGAAACGAGCACTGAGCGTAAAGCTAGTTGTTATACGTCACTGCACCATGTGGCGGGTTATAGCATCCTCCCATTTAGGTAATGCGAATCTTCACAGACATGACGGGGCATGTGGACTTACCGGTTACTTCGGGAAAACTGGCAGACAAAGGTTGGTTATAACCTACCAGCAAGTCATAATCTGTTTCAGGAATTACGCAGTTCTGCCGCTCATCCTAAAAATCCACCGACCCTCGCACGTGCCGAGTTAATCTACGGAACGCATAAGAGAACGGAAGCCCAACTGGAAGTTGGACAATGCCATGAGCGCCCTCGGACCACCCTCAGAGAGGTAATTTAGGGGAGCTAGGTAATGATCACGCTTTTCAGTGGTCCTGTATCGTGCATAGGGAAACCACTCTGGATAGTGCTTCTAGCGAATCGTCTAAGTACCCCATCCTTATAGCCCTGCCAAAGTGCTGGTAGTAGCTATCCGGATCACCACGTTCGGGGGACGGGGCGTGGCTCGTCCGTATGCTGGCTTCGCCGTAGCGCAGTCCGAAAACTGACAGACATAGTGCATTAGCATTTAAACCACCTCGAATAAGATTTGGGCAGATAATAGCGCCATCGTGTGCACTTGTTGCTCGGTGCCACCTAACCCCGAAGCTCCTAAGGCGCGGGCCTATAATCGTTATCCCCTACGAAATGCAAGTGCGTCCTTGCTAGAATCATTTGACTCTCCAGGGCCGGGAGTGATAGACCTTTTCAGATGTGTACCCAACGATGGGTTCCTACTCACGTAGATACCAGTTCAACCGCATAACCGTGAATTTTGGTCCGTGTCGTGGACGCCCGGAATGATAAGCCTCAACAGATTGCCTGTTTAGCTGGTCGATTGTGCCGATCAAGTTGACGTGCTAGGCCGGCGCTAAGCGTAGAGGAGAAATCTCGCAGCTTCGATACACGCGAGAACTTGGGCGTCACTTACATAGTCGGAGGTGTCATGGTTGAGCCGGTATCTCCGATTGATCACTCGGGACCAAACTCTATCTTCCTTCTAGAATCATCACGCCGACTTGAACACTGTCGTCGTTTATCACTGATAACGCTTATCAGGTTACGTGGAATCGAAGGTTCAAGACGGTCATGGAGCTGTTTTCTATTATTTCACTGTTAGTTCTTGGATACTGGCGAAGGACGCGCCACTTAGACTGTGCAGTCCCCAATTGGCTCGAGATTCCATCGGCGCGTCTACCTGACTCAATGCGTTACAGTCTTGGCCTGGCGCTCCTACCCCTGCGGCCTATAACGAGGTGGCTGTCCCGCGTGCAACACTCGCGAGCAACATGCCAAGACTTAGGTATAATAGCTTAAAGGTGTTCGCTTCTTGGTAGATAATTCTGGATCCGCGTGCCCACCTCCCTGTGCTACGAAGTTCCGTGAACAATGTCTAGATGTATAGCAGTGTGCAAGCCACCAGGTTCTATGGTGAGCAGCAATACAAGCCGTAGGTGACGTTCGGAATGACCCGCAATTTGTCGCGCCCCAGAGTAAAGCGAAGGCTTGACACTCCCGACTAGTAATCCCATGTGTAGGCCCCAGCACTAAAACATCTCGTTCCTCCTCACTTCCTGTGCTCAAGCCGCCTGGGGTCGAGGCGTAAGTACGGTCTTGATTGGTTGATTTTTGGACAATATGATGTCTCTACCAGCAACGCCGCCACCGGTTATGTCAGTCTCTGAGTTATAGCTACAATCTCAAGAATGTCGTGCGGCTCCCGTGGATGGCAGACGAGTCAAGACCAATAACAGACGTGTGGCACCTCTGGTCGTATCGTCACCCCCAATTGATGAAAATGTGGCTAGAGTTCCGAGGAGGACTTGCAAAACGAGTATCATTGATCCAGCCCATTACTCCAGTGTCCAAGCCCGAAACTGTAAGAGGGCCATTGAAATAATACCGGCTAAGGAATGTCTCGGGCGTGCGGGAATCATAAGGATCCCTCAGTTGACGATTGGGCGCCTCTTTTGCGAGCGGCATCCGCTGCATCGAGGTAAATATGTGTTGGGGACACAAGCCGGATTGGCATTGCCGGAACTTATGTGCGGCAATTGCAAAAGTCGAGTACTAGAAGGATGATCAATTGCCGATGCGCCAATTGAAGATGATCGCCTAAATTGGCTTGTTCATCCTTCGCTCCTGTACGAAGAACTCTATCCAACAGTTGATGGTTGGCAGTAGTTCCGCACGAACAACAACGGGATGGAATTCACGGACATGTTGGTGCCTAAACTAGCGCCGGTTTACCGGACGTGTCCGTACTCATTCCCGCCGCGCCAGCCAGAAAGGGTCGATAATTGCAACCTCTCTCGCAGTATCCTTTGGTCGGCAGAACGCCATGGAGCGATCTCCTATCTCTCAAGGTCAGTTTAAGAATTATGAAGTACTTCTCGACGTGTTGAACTTCCGGTCTCGGCCGTTAGGCTCGCTCGATTGAAGTACAACAGAATTCAGTTTAACCTACTACTCGCCCCAGAGTACTTCCTATGAATGGCTGAACTCTGACACCGAGTAGACAAGTGGTGGATATACTCTTTACGGGAGTCACGTATATCGTACTATTATGTTTCAACGGTGCTTGCCATCCACCACAACACCGGTAAGATTATCAACGCTTACTCTCAATATTGCCCGCGAGGAGGTCTTATCCAAGGTGTAACAATAGTAGTCTGTAGCGTTGAGATTAGTCTTAGAAACGGTGAAGGGCGTTCTCGTGCGCTCGATACCGCTCCCCCCCAATCGTGTTCGGCATCACTAGGACATACAGCGGTCGCCAAAGCCTTTCACCGGTATCGCTTCTCGGGACTGATGCTGCAATACACGCGTAGTCGAAGCAAATTTATGGTGCCCAGCATCTGAAGCAACTCCATAACTTTTACCGTCGATAACAGGATTTGGTAGTCCGCTCGGTACTAATGCCGCAAAATGAAGCCCTATAATGAGATATCCTAAGGACGTAGGGCGCCATTGTTGGTTAATTCCCCCTACGGATTGACGGGCCGCGCCGTCGGGCTGGGGTTCGTATGAACCTAGCTCCACGCCAAGACCTGTCCCTTGTCATAGCCAACAGGACACCTTTCATTATGGCGCTACGCATATGCGACTGTTCCCACAGTACAATGATGTGCTTAACCATCGTCGCTCGGCGATAGGGTATCTTTTAACTATCTTAGACTGATAACGTGTGGGCCGATAGTATCTAAGAGCTGTGAGGCTTGTGGACCACTTAAGCTATCGACTCCCATTGGGGCAAGTGATTACCCGGGTGCTATCCACAAGACCGCACTTGTGTCCTTGCGTCGAATTAAGAAAGCTATAGGGACCAGCTGATATTAGGTGCTGAGGAGTGCTACCGGCCTGTTTCACATATATCAGAACGCGTGCCCTGAACTAAGACTCAGCCAATCAATACTGCGTTGTGGGTGAGGCAAGTATTCTGTCCGGGGATGCTGTGGGGGACAGTATTGATCTATCATACTAACCATAGTCGACATCTCAGGTTTTCGAGCGCTGACGGTACAGACAAATTTAGGGCGCTACGAGAACAGCATGTCGCTTGAACCGACTCAGGCGCCGTAATTAAAGGGAGTGTGCCATGAACTCGAACGCACTCCGTATCAACGCAGAAACCGCCTTACAACACTGAGCGGCGTAAGAATACTCACTCGATATTGATTACCGTAAGGCTATATTTGTATGGGAAGCAAACGAATGACATTTCCTGGATATACAACAGTTAGCTGAAGGCATATGTGATCTGCCAGATTCCAGAAGCTGATGGGGGATCAGGATGAACCTTGTCAAGGATTCGTATCTGCGCTATACAGGGAGAACTGTGCGATTGTTGAGGCTACGCCGCGTAGCCGAGCCGTTGGAATAAGCAGCCCCGTATGTGGACATTGGTAGGAGCATATTCAACGGGCCACTAAAGGTCGCAATTGCCTACATCAGATGAAAGGTTGTTACCGGGCTAATATCATATAGAGCCCTCTAATATCCACCTGTTGTATGAATACTGTCGCAGTTTCATCACGGTTGCCCCTAAAACACTGACAATTAGGTAGCGGTATCGTTTCTCATCTACTCAAGGCGTATCTTGGGTCGCAGGGGCACGCCGTGGTTGCTCGCCAGTTACTTACTGACGGTACCTCTCATTCTTTGCAATGCGGGTACTTGTGTCGTTGAAAGTAGTGGTACTCGCACCAACTCAATCTATCGCCGCTGCGAGACAGTCCCCGAAAGCCTCCGCAGGAGCAGCGCTACCTCATATCCTGCACGATTAGAATTAACTGCCTCTCTAGAAACGAGTCTTACTAGTAGTTGACCTTGATTCTACGGCCACTCGCATCGCGATGATTGAGAGAGTTCCCCCACTCACGAATTAGGAATCATGTTGTAACAGCGGTCCCACTTGAAGGTGAGTCTCCATACAACGAGTACATACTTGAGCAAGCAACTAGATTATCAAGAACACGCATTTGTCCTAGCCTGAACCACTTTTGGTCTCACATAAGACAGCGGGAGAAGCGATTCGGGCGACGAGGCTGTTAAGTCGCACGGGTTGCTATTCATATAACACCTCGCCGTCGTGTTAATGATGTTTATGAGCCCTGGCGGTATGCAGAGCTAATTGGTTTGCATGGGTGAGGTAACTTGATTCCGTGTTTGGTAACGAGCGGCGGTCTACACCTAGTCTCGGCCATTGGAGACTGTTCGCGGGGGTAAAAAATCAATTATACAGACACTCTAGCCTGATATTGCCCAATTTGAAAGAGTTCAACCTTTCGCAGTTTAGTGAAAACTGAGCGGTTTGTGAATATTACCGGCCTTATATATCAAATGGTCCGGTACCAAGCCTAGACATGTTCGGACTTTGTTCCGTTAAAACCGAAGATTACGCATTTCACGACTCTAATTTTTAGAGACTGCTAGACAGGATATCAGCCACGGTGCGTCCTTCCTGTATCGCTACGTACTTGCTCCTCGCCTTCTATATAACGGTACTGGCGAATTCGACAATACCCTAATAGGAGCTGCGACTCTCTAGACGACCAGCATGCAGCTTATTTAAGTCACACAGATCGTAAGAGAGCCTCGCAATGCTCAGGATATCGGCTGCCCTAGAGGATTAGCGGGAGTTGGCTGGCGCTATTGAATGTGTCAGCAATGGCAGCTCCAGGATCGTCCAAGGAGCCGCTGGCCCGTCCCATATGGTCTTCGTATCAGTACTGATCAAAAGGCGCAGCGTGAATACGTTTTCCTCCATAACATCCAGTCAGTAGCTGATAACGTTCTCACCCACTGACTTCCAACAGGGGCGATGGACCTCCAGGCGAGCCATGGAGTTCGACCCCCTTGAGGTATAGTGTAGGAACGGGATAGGGATTAAAAGCGTTGTGGTTTACTCTAAGCAGGCTAAGAGGCATAATGTCAGCCCATCAGCGCGCGGTTAGACCTAGCCGATTGGCGCGTACCAGGAAGCCGTCCGTCAATTTACAATTGGTCGTAGTCGGGATACCATCTTGAAATGCGTAGTCCGTCGCGCTTCGGGGCGGGCTTGAAGTGATCATGTGCACCCTTTAAAGCCATAGCCATACAACGTACCTCGGCTGAGTAGGTTCATTCTCTTGGAAAAATACCGCTAAGATAGAGACACCTAAAGTAGGCTTCTTAATAGGGCATGTGTTTCCGCCTAGCGTTGACAGCATGTGATTAACCACTTGACCATCTGTCACGCGTCATGCTGAAGCTTACCCTTGATACACGGGCCGTTATCCAGACGCCTGGAAACTCGAATTCATCAAAATTCCTCCATTTCTCTGGCCCGACAATCCACTGTAGAGTGGGATCGGTGTAATACCCTGAGTTTTCTAAACGGCGACACCGATGCTATTTAGTATGCCACGCGCTTCGTACTGTTGAAAAGCAATTGGAACTGGATGTCTATCCCGTACTTTTAAGTCGTAGATCCGCATCATCCATGCTAATCGTCGTCATTAACCAATCACAGTCTTGCAAAACTCACACTGGCTGATTCTGTCCAGCGTTACCGCGGTCCTGTCCGATTAAGAGCTCTCTCTGCCTATTTTCAGTTCCCTCCAGGCGTAAGGGACTTGATGTACACGCTCGACGAGTGCGGCTCTCTGTGACTAGAAGTCACTCGGGCTAAAGACGACTAGAGGTTTTTTCTGCGATCTAATATTAACCATACCCTACACAAACGCCCACCGGTTTTTATCACAACCACAGTAGCGGAGACGTAAATCGTTGTGCACAGAAAGTTAGGTAAGTTATCAAAGGGCAAAAGAATTACAGGCCATATTCTTTCAGTGTGACCTTCGAGTGCGGATTAAGTCCGCGGCAAAAGCCTAGGGACGACATCTTAGTAGGCTATCTCCACCCAGTATCTGGCGCGACGTCAGGTGTCAGTACCATGCTCTTATGCCCCCCTTTAGGTCCACCTAAACCTCGAGGTCAGCGATTGACCCATGTAGATACTGGTAGACGTCGGTGCCACTATGATCGGTTTTGTCGTAATTCACGAGCATTTGTCATACTGTTAAAAACAAACTTTGACGACAGTTTGGTGCTAATTTGAGAACCCACGTGGGGCCTGCCGCCGGATGTACGGTATGATCTCACCGGGTCTCCATGATACCCCCATCAGCCTCATGTTCTGGCCCGTCCTCAGAAGCGAGCCCTCAGTCCTTTCTTAATCTCCAGTTACTTATCAGGGAGTCCAGAAGCTCCGGGTCTTCCAAATCCTCCGCGATGTCTTAGTCGACCCTAGGGACACCTAGAGGATAGTCGCATTTGTAGTGTAGCTGTCCGAGAGCAGAACGCTGCGGCAGGCGGACATTGAAGTTACGGCTATGTTATCAGTCATCCTCGGCTTATAAGAGGCTTTGGGAAAGTTGGGTTAGTGGCCCAAACGATGATATGCACCAACCAAACTCTTTCACAGCAATCCCGCAGAATAATTGCGGCGCGGACGGGCGATGGGCCAGCTGCTAGGGTAGCGACAAAAGGACCACCAGCTTCTGTCTGAAGACAGGGGCCACCAAACCACCCTTGTCCAACTCGTATGCCCGAACAAGAATCGAGATCGAATTGTCACTTATCATCCCGTACACAGTAGGTCCCGTCTACGTATTCCATGCGTTGCCGCAGGATTTACACCAAGTTTGGTCGCCGGTCCTCACTCGCTAACTACAGCTGTGTAAAGCGCGGGCGAGGGCGATGGATACGTACCCGAGGTTATCAGGCTGAATTGCTGGTGAACACTTAGGTACGACTCATACGCGGGAACCCGGCAGAACTGTACATTCGCGGTTTTTGTCCTCTAGCTATTTCCAAGAGCTGATCACGAGAAGTCTCTCCACGCACATCGCTGAAGCGAGACCCTCGCCAAGTGTTACTTATAGACTTCTATGCGGCGCCGCAGTTTATACAAGTCCTCGCTCATTTTAGTTCGTGCCTACACTGTCACTCCTACGGTACGCCACGGCGCGTGGTGATGAAAAGGTTTCAAGTTCGTATGCGAAAATACAGGCCATTTAACACGGACTCCGCGTCCGGGCGGGGCCGTAACGTTGCCCGTACCCGGACAGTTCCATTGTGAAGCACTACAGCTTCAATGTTACCAGTGTAACGCCAGCATCAAGAGTTGCAATGGTCTAAGCGTCACCTGAATTTGCTATATCCTGACGAGACAGGCGTGCCCCATCGGAATGGCAGAGGTAATAGGCAGCATCCCCGCGGATCTTCATCTGCCGTCAACAGCGCCGGATTTGTAGGCGGGGCGATAAGCACTCGGGGGTCATCGTTTAACCACCAAATGGGCAGTACAGGTGTTCTCCTGTCGGGCCGTGTAGTTAGTCCGACAGGTGAAACAATCTGTCAACGAATTGGCGCCTACTTGGTCCGCCAAGTGAGATCTTGAAATTACAAGTCTTTCCGGCGCAATCAGGCCACGATACTGGGGCAACACCCCGTTGGGACGACTGGTAGAAGCTGGACTCCGGGACGGGGCACAAGGCGGTGGCGGCATTGAACAAGCACGCACGCTCCTCCCTATACCTACGACAACTTAATCTTGTACCAGACAACCTAGGAACCCTCACTTGACTGCTCAAGCCGAAGGGAACAACCCCCTCCTTGGACAAAGCTTACTGCCAAGGCTTGGTACGTTCGCGTGTCCGTTCTGTATCGGGACCTGAATTGCGTGTGCAAGCGTCATTCGCCATGGCCACTACGGCCTGGTCGGGCACCCAGTGTGATAGTCTTTCATGCGAATGGCCCAGTGCTATCTTGTTCGCAACGTTCTGTAGATAGAAGGCCGTGGAAACTGCGACTATCCGCCGCACAACCTTCACGGGCCCCGCCTCTCTATGGAATACGTGTCTCATGTGCGATATGAAGGTTGCCCTCCATAAAGCAGATAGTGCTGATGTGCACTACTTGGTACTTTGAAACGTATTAGTCTCACCTGCTGATGATTCCTTTAAAGCGGTGCAAACAGCCTTCGGCAACCGGCCACTTAGGCTCGACGGACACCATGCCTTTCTGACTTACAAAATGACCACGCCCCTACGACAGCTGTCGTTACCAGGCATGCCTTAGCTGTCAATGGCCTCATCCTGCCTCCTAAGGGGGTATGTTCTCCTAGTAGCCATGTCATAAAACCCCTGCGCGAACCGGGTTATCTACGAACAGTACGAACCCGGCGCGTTTTGGCTAAAGTGGGGTTTATTCAGGGAGCCCGACATACCACAACAGTAACAATAACACACTAGCCGTTAGCAGGGTCGACGTGCTCCCGTTCGCGGAATTCTGGCTGAACGTAAATACGCACCTGAGCGAATTTTCCACGAACACTTTTACATTTAACCTCGCAAGAACCCTCCCCATTAACGAGCTGAAACGCTTATAAGAGAGACGTAATGGATCAGAGACCATCTCCTCCGAGAAAAGTCTGGGTGAATCTACGATGGGTATCTGGAACCATGCTCCCTCTTCCGGAGGACAAGCCCTTAATATGGAATCCAGACTAAAGCCATAGCGATAGCAGCTTAAAACTAAGGCACGTCGTCCAGCCAATTCGGCCGATTCCGTTTGGAACAAATAGCTGTCTGTCGCAAACACGACCCTGGGAAATGATCCAGTTCTACCGCACCAGAAGCGACCCACCCCGTATTCGCGTGGTGTTCCTTCAAAAACGCCCCCTTGGGACTCAAGACGTCGAACTTCTTTACCCCAACCGTTGCGGGGTGTGTGAGAAACCGCAGACTTGAGAGCCCGAGTATCTAATGCAATCTTCTCGGGTAACAAGTGTGTGTACATCGTGACAAGTCCTTGGGGTCTGCAACAGTATGTCCGACCAATTGACCGACCGCAGCATAGTCACAGTCGGAACTTTCGGAGTAAATCCAGGAGGGACGCCTATAAACTGTTCATAGGTGTCAAAACGGGCAAGGAACCAGAGAATGATTCAGTGCATTCGAAGAGTGGACGCGGTAACGACGTATAAATTTCGCGCTTCCAAGTAACACCGGACCGCGATGTGTGTCGCATACCGAGTTCTATGACGATGCTCAGAACCTTTGTCCACTAGCTTGCAGTTGCTCGACCCTAAGCGTTGATCCGATCTGTGTACAGAGAATCCACTTCTTATCTCCGTTGGCCATTAAAGCGTTTGTGTCCAGATCGGACTTGGTGTGTATGTAAGGCCTGATACCGCACAATAGGAAATATATCGGCTAAATTAAATTGGCTCGGGATAGCCGATCTCGAATACGTCCATTACTGAAGCAATTGGTTACGCGCGAGCCCCCGATATTGACTTTGATAGTATGTCCAAACGAGTACAAACTCGTTGCACTTAAGTTCGACTTGCTATGAAACATAGCCGTAGGAGGATTTAACCGAGCCACAGGCGGCTCCCTCTATCTTAGCGGATCGAAGTAATATTCTGTTGTCATGGCTTTAATTGGGAAATGGCTGCCGAAATTTGGCGAAAGATAACAAGTTAATAAGGACAATTCCTACTTACCAAGGGTACTGTTTCGCAGCGGCCGGTACCCCTTCGAGACTCTGTTGATTTTCCGTGTACACAGGCAAAATGCATTGTATATCCCGGATTGCTTGCTGCTCATTAGGACTTTACGACATTAAAAGCAGACCAATTTGACCCTGCTAACCATTAATCAAGGTAAGCTGCTCTTTCACGGAGAAAGCGCGTGTCTGACTGAGTATATCTAATAGAGTTAGCGTACAGTAGTGATTGGCATGCCATCGAGAGGCGACGTCCGTAGTCAACCTACACCGTTAGAGAACCCTTGTCCGTTGCGCTTCTTAATCTTTTGTCGAAGAGGAAGTACATGAAACAATCAGATTAGTCATTATGATACACATCGGTTGGGACACATAATCTTTGCGCTGCAATACCCTACAGTGGCTGAAAGAGTGGCGTTGCACGCGGACTAGGATTACAGCGTATGCCCAGGTTCTTCGTACGTTCCTATGGGGCTGTAACTTAGTATCAGACAAGCTTGCAGACCCGCGCCCGGGCACCGTGCTATCTGAGTGCATGCCGTCGGCGTAAATCGTGCAGTGATTCTCCTCCGCCAACGGCCCTGAACAGGGTTCGGTGCTACTACTGTGGCAGGGGGGCGGGGTGTATGTTACCACAGAAACTCCTCACGCGGCAGGGTTGACGGCCAGTATACGCTATGAAAGCCAACAATTGGAGTATGAATCCCTCACGAGGCTTAGCGATGCAGAAGCTCGCCTGTAGACTAGTCTTACTAAGTGAAGAAACGGCGGACGAAATCGAACGTGGGTTATGCTTCGATAGTCAACCATGAGTGCATTCAGTAGAAGGTCGGAGAATCCACTAGTGTGCGGAATTATGGGTTCCATCTAAGGCGAGAAGGGTCCGGGTTAAGTCCAGCTTCTACACTCAGCAGGCAAACATACGTGGCCAGGCTCCTTTTAATCCCCGGAACAACCCACTCCGGGGGGTGATCCCGAAAGATAGATTTATGTTGAACAGGCAGTAGCGATTAAGGCAGCGGGAGTGGACATATATAGCAGCAAATTGTCTCCCTCGGGCCTTAGCTCTAGCTCCGGATAACATAACATACCTGTGCATTTGGCAGCAATGATGATCTTGTGCTAGGTTGACACTGGTTGGCGGACAACGCCCAGTAATGGGACTAGCCTGTGGCAGTTTGAGTTTATGCGTGAGCACAGAAGCGCGCCCGTCTTAGGTTGCTTCACACGGCCGATGTCACGGCAAATTGGTTTCCAGGGAGAGATTGACGTGTCTTGAGTCTACGCTCCGCGTTAAATACACCCCCCCTGACCACGTTATTGTGCGTTTAGACCTATTCAGTTCAAGGCGTATGGGAAGACAGCCCGGTAACGTCGCGGTCGATGTCGAGATCCGCTGCGCCCGTTCATAGACGACAGCATGAGAATCGACGGTCTTGAACGTTAACAGATCTCAAAGTCGTTAGCATAAAGCTCCTAGACCAGTCCGTATTGCCGAATGTCCTTAGACTGATAGGCTATGGCTGCAGACTCACGCATCAGCCCGGCGGGGCTTCAGCGATCTAAAGCTCGCTCCGAAGAAGCTCGGGATACTCATGAAGGGAACTTGAAGAGTTATATCGAGCACGGAGAGACCACACATAGCCCTCTATAGATTTGTAAAATTAATGGGATTGTCATACATGCCAATGGTATGGGCTAGAGGCGCCTGTCAGTCAAGGAGATAATTCGTACTCCCTTACTTCAGGGTAGATCATGACAGTTCAGGTGAGGTCATCTAAGGAAGGTCGCTCGGCTGTAGGGGTCTCGTACTATTAGCCCACCTCAGCCCATCCGCCTTCACTCACATATTGTCCCCCTGGCCTAATGGAATGGAAGGTGATCACTCTGGTCGGGTACTACCACCATATAAACACTGTCGCTGTAATTGTGTTCACTAAATACGCAGTCGAACGTCCCCAGTCCACGTCCGGGTGATGCCGCGCTCCCAAGTGGAAGGTATCGATTTAGGAACCATCGATGCTAAAGACTGTATCCTCGTACGCAAGCTACCGGGAGACACCTCCGGGAGCAGTGTCGGTACGCTTGTATAACATCCTGACAAACGCGTTAGTTGAACATTAGGCGTGGTTCGCAAGGTCGGCACTCGCTGAGACAGTGTAAAGTTTGGCGGCTCGTTACCATGAGGCCTTTTCTTCTTGGGAGGTGTTAACCCAGGGCGTGTGCGTATACGCCATAGGACTTACTAAGTTGTGGACACCCGCCCGCCTTTTTAGTTTTAATAATGCCCGGCACCTTTGCTTATGCGATTGCAACATCGCTGCAATAAGCTCGCTGGACGTATCAGGCCGGAGAGATGCTATCGCGAAAGGATTCTTCCCTCGCAGCGCGTTCGCATTCTCATTTCGATAGAGCTCGATTAAATCACGGAACGCTATGGAACAAGTGTGCGGGACCGAGAGCAAAACGCACGTGTTAGCACCTTGACCTAAGAATTGGGGATAAGGATAGCCGAATGAATGCACTTAGATGCGTTTCGCCGCCTGCTACCACATGAGCTGAGACAATTAAGCGCAGAGATCATTGGTGCTGTCAGTGCAATACCTATGTGGGCCGCCTTACACTAATTAGACATCCGCAGCCGCCCATTTGCGGCACGAAGGGAAATCCGTTAAACACGGGCCGTCCGAAGTCCACAAGCACAGGTCCGTGACCCGTGATGGTTCTGTTTTAAGCCATCTTTTGGCGTTCTGTCGATGAAATGCTGAGGTTAAGTGCGCGAAGTTGCTTTCCGACGAGACTGCTCCCTGCCGGCGGGTACGCGTACAGACCCTGCGGTCCGCGGGCGTGATCTAGATTACAATCGACTTCCACGGCTATCATCCGCTCGTTTGCCATGGAGTCGTGACAACCAGTCTAATTGGGCTATATCCCCTGCGCGAGTACTCCGCGGCCATAGGTATGCGTTACAGCGTTCCGGAGCAAAGCGTGCACTAGTATCTTCATCCATGAGGTAGACGATAGGGGTGGGATCGACTCCGATGCTAATGTCTAAAGTCCCCACGCATCTATGTCCCATAACACATGACCTACAGACCTTCTGTTGTTAAGATGGTGTTTGTCCGATGAATCGTAAAGACTAGCTGACTGTACGCAAAACTAGGTAGTTTGCTATCTGACCATGGGGTTTGTCTCTGTCGCTTTCGAGGGAATAATTAAAATCCGGGATGCGGGTTTCAGGCCCACGTAAGGCATCCGACTATCTACCAGCATACACGAAATTCTAATGAGTTCAGATGCCGTCTAAACAGCTGATAGTGACTGCCATCCTAGAGGACTCGCTCTCTTCTTACCCATGAGGTACTGCGTCGGAGTTTACTGACCACCCCCGATCCAGCTAGAGCGATGAAAATTAAGTTTTACGGACCATAGATGGGGTGTATACATTTACAGCAAACAATCGCCCTTGCTCCTAGAGTTACATACACGCCTCTACGACCTGCCAGCCAGATCTCGTTATCGCCCAAGGCAAAACTTACCGCAACGCGAGGCGCCTTTGGGACGGCTGCCTCATATAGCCGCCATACACATGACTACCCAGCGACGTTTGTAGAAGCAATGGGCGAAGAAGGACGATTCGAACACTATCAGGGGTGCTTCAGTTTACCTGGAAACGACTTTCTCTGCGATCCTATTCACGTCCTAAAGCATCTCCGCTAACTCGACGTTGAGATGAGCCATTGGGCTGGAACAACAGTCAGCCCCTAATGAGGCTACCTCGACCAGTTTTGGTTGCAAAAATCCGCCCCCGGCTCTCCTTACAATTTGCGGTCGCTTAGAGACATCATTATTCACGGTCGCCAGGATACTATCCGTACGAGACCTATGCGTAGATTTAAGACCCGGCATTCGTTTTTCCGGTGTATAATGATTCAGTTATTACCATCCACATCTAACATCAAGAAAACCAGCAGGCGTGATCATGCTTTAGGTGGGTCCAGAGGATGACGACAGGCTCTTGCTTATATCCGTTCACTACTGAGGTCCCGGGGACCCACATAAGGAGCATTGGGCAAAATACGATTGCAGAAGGCCGCAGCTGTGCTACCAATTCTTGCCTTCCGTGTTTCCCTATCACTAAGACACCGCAAAGTCCATCAGGTCGAGTCATCCCCAGCCGGCAAGCAGATTCAGGTAACTACACAACCTCACTGAGCAGCGACGGCTTATAAAAGTGCGTTTGTTAACTTAGGTCTTTAGCTATAACACGTGGCTGATCACACTCATTCATGTATCATCGGCGCTAATGCGGCAAGTGGGAAGACATCTAACCGAGGGTAAGAGTTCTATCTTAGATCCGGTATCGTCAATACTGACGCGAAGTTGCGGACCATTGGAGTGCGCGCCCTCTGGCTGTTTGGGGTATTTCATCTCTGAACATTTAAACATGTAAGAGGTTGAACGATCATGACTCCAACCACCTTCGCCCAATTCGAACAAGTTGACGGCTGTGTGAGACCCGCTCATAATACCAATAAAGAAGGTCACAAAGCTTAGTGCACGTTTGATGTGAGCCCAGCCCGCTAGAGGCCTGCTAAAACCTGCAGCTGACAGGGGCGCCAAGACGCGAATCTGTTGTATTACAAATCAAAGAAACCGACACATTTTAGACTACGAGCCAATTACGATATCGGGCCCCCTTCCCGCCGAAGAGTTTGTCAGTCACATAATGATCGTATGTCACCGATACCCCTGGAGGGTCCAAATATAAAGAACAGTCATTTGTAATCTGGGAAGTCACAACATTTATGACAGGAGATAAGGTTATACAGCCTTGTAAGACTCGGATGATAATATTCGCTCTATTGACTGGCAAGTATTGCACTATTTGCGAATTAAGAAACACCCGCGTCCCAGCTCGACATTCCCGAGTGTTCATTCCTGGTCCCATCTTGACCGGGTATGGACTGGGTCCCTCGATGAGCACCTGTTCGCTATCATGTGGGCCGATACATCACACACCCTGATCAGGGGAGTGCCGAATTTGCACCGTCCCTGTGGCATGAAGTCTGGTGCACCGGTTACAGGGATAGCCATTGAATTCAGGGCCTCAATGTAACCAGTAAGAGCAGTGGGAAAATGCTGATGAGTTCGGATGTGGTTGTAGTCGACAGAGTACCGCGCATACTGCTTCTTGAAACGTCCGCGAGGGGATATTCGGCTTGTCGGATTATGGAATGGGATCTCATAAATCTTGAACAACGAAACACTACATGCGTCCCGACCGTGCCAAGTCATCTATTTAGAGTGCGCTTAATATATCGTAAGTAAGTCTGCAACTGTTCCGGCCGTACTTCTTTGTGGTTCCTCACAAGTATGAACCTTGTGCTCTATTCCACCGGAAGCTGGTGACTGCAATCAGAAATCGACCTGTTCTCGTTGACTGCACCGGCTGACGCTTTCATACTCTTATACGGACGAATGAATTTCTAGTTAAAGCCGCGACTTTTTAGGAACAGAGGCACCGGTTGTATCTTCGCCCGGAAATATTGGCAGCTTTTGTTGCGTAGTTATGGCCATACTAATACCGCCTCATTAGTCTATATTGTTTGGGCACATATATCATCACGCGTACCCGCCCAGTACTAACCATCAATGGCCTCTACGAGACAGTAACATTTTAAGACCCTTAGGCGACTCAAGAACTTCTCAGCAGGGTTCTCGCGAGATCATAATCTATTGCGGTTTCGTTAGCCATAGCAGCATCTTGTATTGTTATCATGTCAGGTATGCGCTCTTGTGAGTCTGACGAGTGGTCTTGTTAGTCGTTTCCACCGCTCGATGCGAGTGAGTGCAGACCGCTTCATGTTCTTCGGTTGCTCGGAATGGAATGGGGCACGCAGGCGACAGCCTACCGTCCTGCCTGGCGAGGGAAGATTTCAAAGTCGCTACCCGATCTGGGTTGTTTCTTAGTCGGCATATTGGAGGCGACTCATAGAACGTTACTTCAAACATGGGATTTCATAGTTGTTTTAGAGCCGCAAGTCTTACCACACGATTGCATAACTTGATCGTATTGCGAAGTTTGAGTCCGGGAAAAACAAACCTCTAATGATAACACATGTCTGCCGGACCGCCTTGCAGTTATCACCGATCCGGTTCATAGGGTAGCCAGCTTCGTATGACCTTAGCCGATTACTGTAGAGGCAATTGCAAAGTCAAAGCGAAATTCAGGCGTACCTCAGACATAAACGGGAACCTCGTCAGCAAGATCGGTAGACCTAGGCTACTCACGCAACGCGGTATATGCCCGGTTACTACGCGACCACGTGATGTAACCTGCTGTGTTTTACCTGGATTGCCATCGCTGGCAGATAAGTATACTAGTGATCGTGTATTCAGCATTAGGTTATTTAGAGAGAACCATCCACGTCAGGTTATTGTTGTTAACATCGTGTCGGGCTCCATCAGAGATATCCGATCTACCCTGTCAAACAACGCGAACACGAGACAACTTTTTGCGGCGCCATTTGGCCGCCAGCCGCAGGCCCCCAACGTGGTCTTACCATGAAGGGGAAGCACTTGGACGTGAAAACTGAGGTCGATTTAAGTTTGACATACAGGACTCTACGATGACCGTCGGGTGACCAATAAGGATCTACATCTCTATTCTTCGTAAGCACTGATGGTAGTATTCCAGTAATGGGAAGCTCGCAGCCACTTTGATGCTCGTTTGATAAACCCATATCGACCAAGAGCCGGCGGAGTGGCGGTTTGCTTATCAAATTCATACAGCCTGAATTTGGTTATCAGATGCCTAGCCCCTGAAACTGCAGCTCAAGCCACTGACTACAGAACTGCCCGTTTCGCCGACATCAACCCAATCGAAAGCACGATGAATCTATCGGTAAACTCATCTGTGGATCCAAACAGCATCGTTGGCCAGTACGATTTTTGCATCCCCTAGGACAGGCGGGTCCCTAGTCCGCTTGGGGCCACAGCTTGAAGGATTAGAACAAGTCGTGAGGATAGTGTTCTGTACTTTACTATAAGTATTTCGAAACTATCCATCCGTTGAGTTGACTCACGTTCGCCATGGGTTGAAGATGGACCTTCAATGGTCCAGTGTGCGCAAACAACCAGTAAACGTATTATCGTATCGAGGCAAGCGACTCATCACGAGCGCCTCGTTGGGATCGCAGAAGGGACGTAGCTGGTCACCCCAGCTATTAGGCCTGCATTGACTGCCCGCGTCATAATTCGTGCGACAGTCTATCCCGGTACTCAGCTCTACGTTATGTCTACTAGATACTCGGCTCTTGAACACCTTCCGGGCAGGACCGGAATCCCTGTTCCAGTGCACGATAAGAAGAGTTTTCGCTTCACTGCAATAAGCCGTCGATTACACAGTGAATGTAAAAAGAATGCTGGCCATGAAAGCATTGTACAACCATGCCCAGGAGGGTCTCGGACTCTCTTTCGGACAACCGCACTGGCCTTTAGAGCTGGAGCGCGGGTAAATTTCGAGGGGGTCGACTTTTTCGGGTGATTCCATATAGGCGATGTGAGACACGGAACATAATCTGTCACGATGGATGTGCCCCATGACGACCGTTGACGTACGACAACTCGAATTCAAGGAGAGTAACGAAGCGTCCGATATAAAGTCCCAACGTCTTCCGAGATCAGACCCAACTAGAGGATAATATTGTGCCAATAAAGACAGGCAAGCACTGTGGGGTCGTCAGTTTTGAGCCTAGCGTATCGGCAGAAGCTCGCAAATAAAGTCACTGACGCACATCGGGTAACGTGGTGTCCCACTGGATTTAGCATTGCAAACGGCTCAGAGCGCGGGATATCGGTGTTCTCGACTCCGAATGTATTGAGTGCGCCGAGTCGCCTCGTTATTCCGGCTTGAGTCGCTCTCTTCTGGGATATGAGAGAATGCTTTCAGCCTCTGACATCCGCCGCGCATGAGAGAGAGATGGAGATAATAGGGTGTTGGCATTCGGGAAGGGCGCTCAATGCCTACCTCGTTCCCCTCATGGTTCCCGCCTTAACTTGAGGAAAGATGGCCAGTGTACTCGGACCCCCATGGAAGATTGGTTTCCATAGATTCCAGCAGACCTAAACGCTATCTGTTCTAGCACGTAGGTCGGAAAAATAACGGCCGTAATTGGTTTTTTTCCCAATATTACAGCCCTTCCAGAATTACATATCGTCACCAACTAGGAATACAAAATCGAGCCAGATTCCCAAGCGCTCCCATATCTTTATGGTGCATTGATATAGCCAAACCCTGGTAGAGAAAGGGTGGGCGTACATCGTCAACTCTTCTGAGTAAAGTCTCAATTGAAGTGTCTTACAAAACGATCCGATATCGACTAGCTGTCTCTGTTCCTTCGGTGCCCAATAGACATTGACAAGCTGTGAAATGTTGGTTGCACTAACTTTGGGAAGCTGCTACAAATGGCATAACGATTACGACCGACGGGCTCTATTCCCTTTTGCCCCATCCTACTCTGTTATCTCGCAAATCCCAGATGTGCGACCTCCTAAACAGACAGAGTGGTGTTCCCGCGATCTGCTAGAAGCAGAGTGGTCTGGGTACGACGTACCTTCCTCGCGGAAAGTTAACGGGAGGGTTACCCTCCTGATTAAGCTCCGCGCCCTCCATCACGACTCCGATGGCCCGTTCAAACGACCCACTCGATATAACAGGACTAAGCCACCGCGCAGGGACCGCTTGACCTATCGCCAGCCCGTTGCTGGGGGAGCCTTGCTTTGCAAAATTAAGCCCCGAACCGGACATTTGCGGTCATTGCAAGGGCAGATCTACTCGTAAAGTTTCCCAGTATCGAATAGCTACGAGTAAACGGAAGCATAAACGCATCAGTTATTCCGGGAAGCTCTCTTTAACGTTGCTATCTCGGTATTAAACTCATTTTTGCCTCCGTCACTTGACCCCACCGGAGACAAAAGGAAGCGCGCTCTAGGCGAGGTATCTACTCGTAACCGCATCCACCCGAGCGTGGGTATTTGGCCTTGGTAAGGAATCTATCGATCATCTGACACGCTACTCCGGCTCTAAATAGCTTCGTTACGGGGACTATTCACAAATCACTGGAACCCATCTTTGTAAAATTGGGGGGCTGGGGCCATACTCAGTAACTAGGCGGTTTCGTTATCCACAGTAAGCTAGCTTGCCCCTTCAGTACAAGATTCAGCACTCTATGTCTCATTGCGGGTGCGGTCCTGAATGACTGTATTTCTCCAAAAGTCCTCTGAAGCGTCATCATCGTCAAGCTCCTTATCCTCTCTAATTGTCAATATTCAGATGTTGCGTCCATCGGAGCTCGGTATGGCGTGATAATACCAGAAACGTGTTAAATGAATGCTGACGGAAGCCGTTCGACCATTCCCCGAGAGTGCATGGTCGTGTGGCGACAGATCCTTCATTTACGCTACACTTTTGGCGGTTAGACCTCACCTTCCAGGTGTGTCGTGCGCATCATTCGGCGCAAATGACAGGTTTTGCCGACTTGACGCCCTATCCGTGGCACCCCCCTACCTTCGTGAGCGTTGGCCCTGCGGCACTTCCCCAAACCCTGTACATCGTGGGAGATCAGAGACACTCATAAGTACTAGCGTTGGAAGAACCGGTGTTGGCGGGTGTCAGCTCTCTCTGTATCACATACTCTGAAGTCCTACCAAGAGGGACGCTGCCTACGCTACGCCCAGGTAAAGGCATTGGACTGCTTGTTTTGTTCGGCGTCGCCCATTCACTACATCGTACCCAACGGTCTAAATTGTTGGACCAATTTGTTCCACGGATGGGCGAGCTGCATCACCTCACAGCGGAACCCCTTCATAATTCGCGACCTTCCCGCAAGGTGAGGTATAAGGAAAAAACGGCATCCCGTGCAGTCGCGGACCGCCACTGGACAGGTTCTGAGTACTAGATGGGTGTGGCCGAGAAGATCCGGACTAAAAGTCGCCTCAATCATCCGTTACCAGTTTCTAAGTGTATACGTGAGCGACACATTAGCTCTGGGTTTCACCACCAGTCGAATGCGTCAATTCAAAATTGGCGTCCTCGAACACGCTTTACGAGCGATGCTCATCGCGACACTCCAGTCACTGTTAAAGGTGTTCCGTTAAGGCAAGAGCAGCTCCACATATAACGTCCATGACATGTTGCAAGCCTGCACCATACGTCCTTTTGGAGCCGTAACCTTTTCCGGAAAGAGGATTCAGGTCAGCATTTTAGGTCTCTATTAGTGACATTGCGGATTCGCTCCGTTAACTCAAGGCCATCATTTTGGGCACTCCTCGGAGGGACCTAATTTTACTCCTACTTGCGCGATATCGATTGACAAAAGGAATTGCGTCGTATTTTCCATTGATATAAAGTGTACTTACGGCCCTGACATATCCTCACGGACACGCCAACACCACCCCGCCGTTCACGTGCCCCCCCTCGGGCTACCAACTGCACAAGGGCACCACAGCTTGACATCCATCAGCATGTTTTTTCGACTATTCGGCCGGCACCAAGTTGACACCGCCGACTGACGCGTGGTCAGCCGATCAGAGGCACCAAAACGGGGTCGCATGCCTTAGACGAATAAGGGTGCCATCGATGTTGGGTATTATTACCGAAACATTCGGATTAATAGTTGAAATAAACCTCCTATTCCAGAGTACTTACCCTAGACCTCAAATAAGACCTGCGAGTGGATGGTCTTAACAATCGGGTGGTCGTGGTCCCGGTTTGGGATAGCGAAGGATAGGGCAAGAGGACGTCCAAGTCCAGTAAACTCCAAACAGCACGCTCACTCTAACAGGGCGGTGATAATGGGGTAGTTAGACGAGCACTCATCGAGCAGTACTTGCAACTGTCTTTCTCCAAGCGACGCTTGTCCCAATGGCATCCGTAGACGACGATGTGTCGGTCCGCCGTCAGGGGAATTATTCGTATGATGCCTCGAGTCGGTCTCGGGAACTTTTCTCGGTTTCCGGTTCCTAGGGTTGCATCCCTAGGTCCAATAATCATCTGTCGTGAAGGGGCGAGTCCTTCGGGGAGATGCTAATTTCTATTGGCCCCAACCAATTTTATGAAGTGTCGGGCGGCGATGTAGTAAAATTTATTTCTATACCATGAAGAGTGCTCAAAGACTGATCCAGGTTCTGTCAAGCTTTTTCTACTATCTATGAGACCCTAGCCCACTATGCACTGGATACGATAACGATGCTAAGGACTACGATGATGCGTGCGGGTATTTACGCTTTGTTGGTTACCATAACACCCACAACGGATCTCTTATGGTTCTTTGATACTTTAAGATCCTTACAATATATCAGACATGTCTACAAGCCCATTCGGTGAATTCTTTTCTCTCTGAAGAGGGTTTTGGCGTTCAACCGGGTATGCTGAAAAGCGACTAAAGTTAGCGCGAGAAACATTATAACACAAGCTCGCTGTCTTAGCAGGTCGGGCTATGCCCAGGAGGGGAACGATGATGGACACGTGTACTTGTGCGACCGGTCATGGACATATCTCTCCGTTGGAGCGTCCGTTCCCAAATGGAGAGAGACTGTGACAGTTATCTACAACTGCCGGTAGCCGTGCCCACTCCTACGGTACCGCTAGTCACAGGGATAGCAGGAAGTTAGTCCCAGTTAGCCATCACGCGGAAGTTATTGACCGTCTGAGTTATTGTTCCCATTATGAGCCTAGCTGAGATGAGTCTCAGCGCGGCTCCGCCTGTTGATTAAAATGTTTCCAGATTAGGTACTTCCATGAACTGATTTGCTCATACATTGACGGCGGGCGAGATGACTACGCTTGCCGACTACGTGGGCTCGGCTCACAAGCTGCGCGGAGTGATCGAAATCAAGTCAGTTGCACATAGCCTCACCCAGCACCCTTGACCGGAGCAAAAGTGCTGAATGACTGCCCGCGCAACAGCTCATGTCTAACTATAGGTCCAAGGAGACAACTTGGAGAACGTTCCTGCGCAATGCTCCCAAGGTAGCCATGTGCCAGGTAAACGCCTGCTAATCTAGTTAAGGTTACACACTAGAGGGGTCCCATTATTGCTCACGTGGGCCACGTGCTACACTTCGCCCATAGCGTACGGTCTTTCACTAGTTCCGGGTACCCACATTACGTACGTTCGTTCACTACTCGCTCAGTAGCTAAGATCGGGCTCTGGGGAGTTCCAATAGAGCCAGGTCCGAGCCATCAATTGTCTGACATATTTTAACTCTAGAACTAAAGCAGCCCAGGTGGGAAGGCCACAAAGGAGCAGCCGGAGACTATCAGATAAATACATACGCACCACTAGTCGTCATAAATAAAGGAGTTGTCCCCATGCTACTTAGGATTCAACGGCTGGTAACGGGACGACAAATAGGATTACGGTTCTGTCTTAGTAAGGCTTATTCTATGGAATGGGGACGTTGGGCCTTCAAGAACGTAAGGGAATGTCAAGTCCGGCTTGGTTTTTTCCTGATAGGCGTGATACGCGAGCTTTTGAGTGTAATAGCGGGAGTGTCTGTTGTTAGATTACTTTTTCCGTAGTATCTCACTCAAACTAAATTAACACCAGTAGGTATTATACGCGGAATCTTCCGCTTTTGACGTAGAGCATCCCGTGTCCAAACCGAATTGTCCTTTTTGGATCGCATGACATAAGGTTAAGAATTTACCACCACTCGTAGGGAAAGACCAAAGCGGGACAGACAACTGCCAGCGGGGCATAGCCTACTTCCTGTTATATCAAGCTCCAGCTGACTCAGAACCAGAGTCAGTAACGCCTATCTCTGACCTTTGGGTACTCCCACGCGGTATCATTGGCGACCAGCTTGTGGAGGATCCATTTAGCCACTCAACTTGTTTCTAGTAGAATTGAATAGACACTGGAGAGATGGCCAGCGACTGATCTTGTCATACACTTGTAGGTACTGTACCTAAGGTGGTTCAATCCTGGCTACGGGTAACAGTTGGTGAGGTGGGCCCTTCCTTGCGTTTGATGGGGGCAGCCTCGTTGGGACCGACTACCTAACCAGGTATGGTTTCCTCGCAAAGCATGGGCCGCCAGTATCAACTTGAATTCCCGGATTACGTAGCAGATTACTCCTGTAGTTCTTACACGCCCTCCTCTAGAGAGGAGCCGCCACATAGGGTACGCTCGTCCTGGGGATATTCACTATACGACTGTGTACTCCCTGGCACTGCGCAATAACCGGAAATAGGAACATGATAGCAAATCACAGGCATTGACCCCAGTGAACAATACCAACCTCAGAAAATGGGGGAACACCCTGCACCTCCGTGCTGCCTATAATACCTCATATCGTCGGCTCTCCATATGAGGGATAAAGATTCTTGTGCTTCGAATTTCAGACAGTCGACCAGTAGAGCAGAATAATAATCGTCGACCTGGTCAGTAAGGGGGCCGGCTAACGTAGACGTTCCCTCACGACCGCTCAACGTGTCTAGACAAGCACACAGCATATTCCGTCCGGATCCACCAGTGTATATTGGTAAGTTGCTCCCAACTGGTCAGGATGATCCTCGAAATTATTTTGGATAAATAGATACAATGCCTATCCACCCAGGTAACACCACTGGTACGCTATTTAACGCCTTCTCCCGGGTCGCTTAACTAAGTATGCTACACCCACATGCTTCAAATATGGTCGTTTCACCCTGTCGGTAGACTCGTCAGACCTTGTCTCATACCCAGTGATTTCAACCGACCAGTGGTGATATAGTAGACCCTGGCGGTAACGATGTATCCTTATTGACTCACCTCAACCCCCTGTTCACACACATTACGCCCCGTCCGGGGCGAGTAGTGCTGCCAGGATTTTGGGGATACAAAAGGTCTCTTCCTTAGCGGTGTAGGGGCGGATTTACCTGTTTCTCAGGTTAGAGTCACATAAGCTCTGAGATAGATATGAGGGCGTCATAGGTTCGCACCGGACATACCTCGCATGTCCCCCTGGCGTAGCCACAAGGTGACTAGAGCCCACCCTGTCCGCGACCTTATGGCCCACATCTCGCTACTCACACCATTGATGTAATAGGGGAGTTATCCTTCGTTCAAGTCCGTTACCAGGTTCATCAAACAAGCTTTACGGATTGAAGCATCCCGGTAAAGACAGTAGCATGACTCCAAGGGCATTTTATAGCCTTAAAGGGCGTCCATGCGGGCCGGCAAGCCACTAAACCTTCATCTCGGACTGTTGGTCCTCTTTGCAAATTCATGAATGCTTTATGCTGGGAGACTAAGAACTTTTGAGGTTTCTATAGTTCAGCGGTGCGACGAAGTGGTCAGGCGCTGTAAATGAATGGAATACTCCTAGCGGGTTACCCCAGGCTTGAGGTTTTCCTAATAAACCCACAGCGTGGATCTCACCCAAGGCGCTAAGCCATAAATCAAGTCCCTAAATGTCCTTTTTAGAGCAAATGATCAGATCTCTGCGCGAAATTTGATCAATGTAGGACCGCAAAACCGCGAAGTCCCGCTGCAATCAAAAGGCGTTATACCGCCACCATTCCCGTGTGCAAATATATAGGCGACACCGCTGCAAAGCTCGGCTCATGCGATCATAACCCCACGCATAGCTTCCTCAATGTTATTTGCACTTCCCCCATCACACTGATATGCCCGGATGAACACCATTCGGGGTTTAATAGCCAGAAGATCCGCCTGCCTAAGATAGATTGTGGTTTCACCGAAGTAATGCCAAGCCAGTAGGTGACAAGACTGTTATCCATTCACGGGTGTAATATTTGGCGGTTCTCCTACAGGGTCGTTCCATGTGCAATGGGCCCTCTTACGACCCCGAGCAGCCTGAAGTCTGTCGAATTAATCTTATTCCTCAGCCCGCGGTCAGGAGGGCCGTAGGTCATACAATCAAGTGAACTCTGGCAGCGTGACGGCAGAAATGCGTAAGAACAGGGCTGTAACGATCCATGCCGGGTCAAGAGAAGGCAAACGGGGCTCTAACGTCCGATCTCGACGAAAATCGGAGGAACCGTCGCTAAATCGCTGTGCGCATTATTTACTCGGCTCTCTCTTGCCCATAAGTTTCTAGGTACGTACGCACCAATAGACAGGGGTATGTACTTTCGGGTAAGCACTGATCGTGGTGTTGTCAATCGGCTTCACTAGTGCTAGTGCTGAGAGTTCACTGTCCTTCTTCCGTGCTAGTTAATGAACCGCTTTCTATCCGGAGCGGTCTTCTTTCGCTCACTTGTAACATGCGCTAGTGGCACTACCGACAAGCAAAGCTAAGGTGCCTCCTCATCGACCGGAGGTCCCTCCGAGTTTAGACGAGCTTTGTTCACTCAAAACGAACACGCTGCGCATAGAGCAGGAATCAGTAAAGGGAACAACCTAACTGCAAACACGTGGCGGCTTGTCGTGTCTGACTACCGGGCAGTTCGGGTCCTAGGCGGTTAGTGAGCGGAACGCGTCGCCGGGCGTATCCGTAAGGATTGAAATAATTCTCTAAACGCCCCGCGTCGAATCTATGTCCCTTAGGCTGTGCCCGTCATTTCCGAAGCGCCCACAGGTAAGAAAAGATGGGTTTTGCAAGGCAAGGTTGCCGATTGGCGTTCGCAGCTGTTTAACAGCACATGCCGCGTGCTATACGGCAAGGAGAGCCTCTACTCATGACCGTCATCACACGCCATATGCCGTGAACCCCCCCGAGGAGTAAAGCGATGTTCTGCTGTACTTACTTCACAATTGTTAGCCGTGGAATTCGCATTCATTCCAACCGTTTCAATGATTCGAGCAGGCGAGGCTCCTGGGTGTTTCGTAGCAGGGCCCAACCACGAACATCTCCTTAAGCATCCACCCACGTGTAGTATGCACACCATAGATGGCATATGATTGTTCGAATGCTACCGTGATGCGCCTGTCTGACCAAATACCCTGAAGTTGCGGGCGCTTGTCCAAAATATGTAGGCGGGACACAGGGCCAACGTATTCCCTACGTCCGTGTACCTAGCTCAGGGCAAGTTTCTTCAGATTCCATTGGGACCCTGTAATAAGCAGCTTTTAAATTACGCTCCCTTCAACGAGACGGAAGCGATTCCGAAGCACCGAACCCTCAGAAATGGACATAGCTGGTGTTGTGGTGAAGCCTGAAATCCGACTCGGTACTATTTGTCATGGGGCTCCGGATATTTGTTGATCTTCGCTGCATTTGCGTCAAACTACGACACAAGTAGGATGGGCGTACCGCGAATTCATGACATGCGCCCCGACTATCATGAGCCAGAATGTAGAATCCAGGCAGTACCATTGGGAATGATTCCGTTGATTTGCAGACGGCGCATTCACTCTAAAGACACATATTGCAAGATTAACCTTCACTTTAACTCATGTCTCATACGGGTTGTACCAGCTGCTAACAACTTGACGTGGATGGCCGGGAAAAGACAGTAGTGGGTAAGAGGCATCTATCAGCGATACCACTTTGAATATGAATTATCCTATTAGAACCGTTCGCGTCGGCTTCTTAAAGTTAAAGGTCAAGAAGCGCCGGCCATCGTTAGGGCACATAGTGGCTATGAGTTGCGAACGTCATAAAACTCGTATTTAGCGAGGTCTCGGGACAGGATAGGGTTGCTGCGTAATTGTACGCGGCAGACAGTACAAACGTGCGCGCGGCGACTCCTATCTCTCCCGCTTAAGCTTTATATCAGCCTGCGCCGGGTGTGCGCGCGAAGCGAGTCTGAGTCCCGGTCGCTAGTGATAAGAAGGCACGTGCTCCCGAATTGCCCCCCTCTAAGGTGTGGTCCTGACGAGACTTTGGATCACGCCTCTGCACAACCAGGGGTTAGCAAGAAAAGCCCAACCTCCTTGACGGCCGTTCGCCCAATTGTAATGTCCGATATTAGGCGAGCTCAAAGTTATCGGGTGCTAAAGCTTCCACTTATCTTTAGAGGGCGCACAGTTGAGGTACGGGCCCGAGAATCGGTTCTGCCACGTAGACTCTTATGTGGTGTCGTATGTGGCGTAGTTCAACCGCGTCACGACGAATCGTCATAAAGGGTAAACTATCCCTAAGGGTTTTGGAATCTTGCGCAATAGTCGCCTTTGAACGGAAGAAGCCTTACCCCTCTGCGTTCACAGGGTAGCACAAGCTGCGACGAGAGTTACTGGTTGTTTGAGGGGTGCCCTAGTAGGACCTCCGCCGTATTATGTACTATCATCCGAGTGGGCCACCGCGCCCGCCTTAAACACATGCTACCAGTCTGTGCGAGTTGCAGGTGGATCGGCAAGGGGGGGTCCGCTACGCATGTAACCATAGGGGAGGGGTAGCAAAGGTGCGAGGACCACATGCCGGCGTAAAAACGAACTCTCACATGTCAGGCTTTGCATTCTGCGCCCCATAATCATCTAGGCTTTGCCCCACCGTAGCGAAACAGTTAATGCTTTGTCGCTCGTGGCTTAACTTCCTACGCGTTCTAGTTGCTACCCGAAGCGGCGTGTGGAGTCTGCGTTTTTAAGACCGGTGTAGTTCGCATGCAGACGTGAGACCCGAGTTGTGCTTGTGCCTTGTGGTACAACTCCACATATAGTCGCAGTGCGCACGCAAGGCGCACTTCGTCGCTGGCCGGGTCGGGTCGTACGTGCGTTACGAAGCAAAGAGTTGTTTATTAGAACGCTGTGATCCGCACGTAAGACCCGTTACTAGCTGCTCCTCTGTTCTTGCAAGGAGTGGTCAGCACGTATACCAGAACAATATCCTGTTAGAACTGTTAGACATACGACACTTCTCCACCTGGGATACGTAGGAAGGTGCCCCCTCACAACTGATGTCTTCCGCATCGCAAGACAACGTTGCAAAATATTACCCAGCGCCGCGCGTAGTGTGCACGTGCTGGTCCCTCGCAGTACCGACGGTAGATTTAACTCCTAAGTCGTTAAAAAAATTGTGATTCTACGAGGAGAGGCCTACGGGTTCTTTCACCAATTCGATAACTTTCCGACCGTCATATTCCCAATGAATGGAATTGAACTGGACAACATATTACTGACATAGAATCATGCGAGTGATCAAGAGTTCAGGAGTAACAGGTGATAACCTCGGTCGTGGGCCCGCGATTAAACAGACCTTAATGCACTGGATCAACGTTATAACTTCTCTGTAATTGGACATATCTTGTATCCTACCCAGACACTGAGGCACGCGGCTGGCAAGCCCCCAGGACAAGTTCATGCTGCGATGGGCTTTATTCGGACTGCCGGGCCTGACCAAGGCCGATCTATGAGTAGGGCGCGGTAAGAGCGAGCCCCGTTGTCCCAGCCGTGCTGAGGGCCATCTGCCTGGTAAGATACACAAGAAATACGCCTAAATGTTCGAAGAAGGCCTTAGATGATGAAACGTTCTAAACATGCGCGCTAACAGGCCACACTGTATGACATTGCCAGTCTCAATGGGGGATACACTTGAATTAGCCAATGTCTTGCCTCGCCTGACACCACTCGACTTCGCTGCACGGAGCAGCGCTTTTCCTTCAGTAAGCCTATAAGGGGATCTCTCTAGTCACGAACTGCGGTTTAACCCGAGAAGACGTTCCTAGTGAGAGCGCGAGCTCCGAGTACGTTCGGCTAGACTCCGTGAATGGGAGACTTAGGAACTAAGCAGCGCGGGGTTTCGTTTATTGGTACTTGTGCTTGAGCGGACGGGAGCACTTCCTGAGGCACATGCCGGGCGGGGTCGCAGGTAGGCTTAGCAGAGACCAGTAGCTCGTCCGCCTTTCCTCCCGAGCGTGAAAGCGGTAGCCATACACGGGGCTAATAGGGAGCGCACCATGCCCACAGTAGGCCAGCCCGGGCCTCACTCCCCCCATTTTCAGGCTACCTGCAGAGCCATTCGGGTTCCGTGGCGTTTCAGAGAGACCTGACTATCGGTTTGTGTCAGCCGATAGTCTTGCGATGTAACACACGAAGGGATAAAAAAGCGGCCGCAGTGTAGTACCAGAGGTATTTAAACGTTAGACCGAAATTGAGTTTTCGAGCCTATCGAATAATTTCGCTAGGGCTAGGTGATCCATTGGTTGAATTTGCACGCTTGCAAATACAGGCAGTGTGTCATCCAGCTCGCCATAAATGTTCAGGCGACTGACAAGAATTCGAAACTCACACGCACTAGTATTAAGCTTGGGTCACCCTGAGGCACGGGCGATTGTTCCGGGATTGATATCGGACGCCGCTTTTTAAACGATGTACAATTATCATATTTAGCCCATAGGCTCGATCATTCAGCCTTATGCGAACCTCGAAGGCAGGCGGAGTTAGTCGCAGTCCTCAAGGTGCCTCGTAACAAATAATGGGCAGCGCCTGACAAGGGTTGATGTACACTCTCACAACACTCTTAATTCAAAGGAGCCCGCTTATGGATAAAACTAATCCCAGCATTATCTCTCTAGGCTTTTTTTGGGAAGCTTAATCTCACACCTTAATTCCTCGTTCGCGGCCCCGTTGACAAACCTCGACGCCCAGCCTTATAGGAACATTAGATACTCGAAATATGGCAGCGAGAAAGTCCGAAGTGGCTACAAAATGACAATTGTCTACATCGGGAGTATTGCCTCGGTCTTTGGTTGATTGGAACGGGGTTGCATAAAGTACGCGTACATATCGTTGCCGGATAGATAATCTCAGTATTATTCTATTTCATGTGTGTGTAACGGCTACTCCGAAGTCCTGTCAATCAAGACGGGGGCAAGCACAACAGTTCACTCACGGATAGCAGATTATTTACGGCTGAGTTCAATATCGGCAGGAGGAATTAATTTGAACGAAAATACACGCCCCCGGGCTACTGTTTAGCAAGACTATCATACGCAAATACTATGCCATTGCTCGGTGGAATTTCGTTTCCGGACCATGATAAACCGTGTTGTTATTCCAAAAGCGAAAATTTTGATTTAGATCGGACCCTAGCATCCAATGCAGGATCTAAAATAATAATGCGGATAAAATGATAAATTCCCTGCGATCGACGGACGCTAAGTATTGAAGAGCATATAAGAATTGAACGGGTGGCTCCTTCGGTTATGTGGCACTGTTTGCTTGCCTGGCAGAGTATATCAACAGTGATCAACGCGGGAAACTCGGCCGCGGTCCGATGCTGTCTGCTTGGTTACCTCCGGTTTACCATCTGGTTCTACGTCCACTTCGTGCATTTTTGTTGGGTAGGCGCACCTGATGAATTGAGCTGCCCCCGATTTCGCACGTCTGACATCCGAATTTTTTGTCTCAACTTGTCAATTCCGGATCGTCCTAGCTCAGAACCCACGGATCAGCTCGGATAATTTGTTTGGTTGTTTTTACACGTTTATCATACGAGCACAATGGATGGGGCTCATACCCCGGCCCTGCCGGCGTGTGACGAGTGGAGATATTCCTTCTCTAGCTGTTCCTTGTGTAGGAGCACGCTTGGTCCTAACCGTAGCCACTTCGCGATATTGAATGGTTATGTTGCAGCTACAACCAGAACTGGTTGAGGGAGCCCCGAGCCTCGATCGTCTTCACGTCCATACGCATTCGCCACCCTAGCTGGGCTTAGACGTTAAACTGCGACCGGGTAATTACCTAATTCAGTCAAGCGTCCCGTTCCACATTAATATTCCAGATTTGCTTAATGGCCCAGTTAAATCTATCATTACGTAATAGCTGTTACTCCCTAAAGCGCCAAACTTTTGACCCCTTGTTACTTACAAATAAACGGGTTGCGTCTTTCTTTCCACGGACCTCCATGCTCGAATATTGTCTCTTTCCGTATTGTACTGTACAACTCGGTGACAGTTCGTAACTACCTTCAATAGCAACCAACCCCTGTTACACCCGTCGGGCTACTAGTTTCTCTTTACAGCCAGCGTCTGCAGGTAGCTCAGCCCTCAGATTCAGACACAATATGAGGCTCAACTTTGCACTGAGTCCGTGGCCGGAGGGCTCTGGCTAACGGTTACGTTAGCATGAAGTACTGGCTTCATAGAGCCGGGCCTAGTCACACTGGTTGGACACTACCCGGATAGAACGCAAGTTATAAGATATAGGGCAGGTTCTGGGGTGTGCCTGGATATTTTTTGTCCCAGGTTCCTTGCGGCATTGCGTTCAAGGTCTCTCTTACCCAGTCGTCATATACAAGATAATACTATCGACAATCTTGACAACGTCTGTTGAGAGCTCGCGTCATAGGGACGGCAGCGCTAGGGAGGTATGCCCAACCGGGAATGTGGGGTTCTCCACACCGTATGTCCGATGGGCACAACTAGACCGTGTCATTATAAGAAGCTACAACCGAGATGCCGCACCTCTTTAATGTTGATCCTGTATTGTGAACTATCACTCAGCTAATTCGGGGCCATAGGATATAGGCTTCTAAGTCGACTTTTCCGATGAAAGATCACTATCCAGCGTGTCAAGGGTAAATGACATCAGGACGCTGACAATTTGGCTGAATCCTTGGCGACGCGGCAAGAATAAAGGCATAGCACGGGCGTTTGAGGGGACGCTGATTGGCTCGGGTCCAGGTCTGACCTCCACGGAGTCCGGATTCGAACTCGGTCAGTCACACGGGAGGCTTAGGAGCCTTCGAACGGACGATAATATCCCGTTACTCGCCACTGTGCCTGCCTATAATGGAAAAGACAACTTTTTGGAAGGAGCTCGCATTGTCCGCGGCCGAGCGATTTCATGTGGCTTTGTGAAAGAACTCGAGTTGGACATAATGTCTGTATATGTATCGCCGACGCGACATATCCTGTACGTGTTGTCGATGATATGAAATTGACCTACTTACATGATACCAAAAGGAGGCGGCCCCCGGAAGGTTGGCCCGAAACACGAGCTCCTCGCAAATGATGTCATGACGATGGCAGAAGCCGAGCTCACGTCTCATTCGGTCGCAAATCCTTGATTCGTGCCGTAAGGAACTTGGGAGGGTAATAGCAGGTGCCACGTTCTCCTATTGTCGGACGCAGTGCTTATGTAACTGATTCCCTGAAACGTAAGCTATTTCGTCCGGAGATAGAACATTATGTCCACAAGGCAAGATATGTTTCCTATGAGAAGAAAACGACGCTTAATGACTTGGTGTTCTTTCTCCAGGCAAGATACGCGAGCGCCTACGGAACAAATGACGTCGTCTACGACGTCCAGATCCCAGCTTTTCGTTCGCTGCGGCCCCCAACTTTGCCAGTAGTGCCGATTGTGCGTTGCGGCAGGGGTCCTTCATACTAGTGCTTCATGCATTTGCCAGGTACCATGGATCTGCACTACTATCAACCGGGGACCGCGCCATCGCTTATGGGGTAGATGATCGCGCCACATCGTTAAGCGCGGATTATCGGAAGCAATCGTCCCACGTATCCTAGGTATAAGATATAAGTTGCAACCGCCACTAATCCCTCACACTTTCCACGGTGGAATCAGATGTCAAGCACTACAAACTTGGTCCACAGATGGGCAAATATATGTGCTCATCTCATAAAAGGTGTGACCGCTCGTTCCGGAACCTCAACTTTTGCTCGTAGCGGGTATTCCTGACGCGATTCACCAATCGGGGCCAACGGCTGACTTAGACCCGGCAAATAACACAGTCCAGCGTAGCTTGCGCATTTACGGCTTTTTGAGCTGGCGTTCCCGCCAGATTTGCACAATAACATCGATGAACCTGTGCTGCGGCTAAATGATAACGGAATGGACAGTTCGCAGTGCTTCTGATTGAGTTCGTGACCAAAGTCATCCGTAGGCAGGGCACTCTATACCTCACGTATGTAGCCTGTGTATCCTTGCCCAAAGGCGCGCGCAGCTCGAGGAGGCGGGATTGACCGGGACACATGTATTCGCCTCCGAGCGAACGCAGTAAATATTCATACGCAACGAAAGAGCTTCTTACGGTATTAACAATTTCATCCGGGGGTTATCGAGGATCCGCGCCACGGGTCTGCGCGAGACTCACGTGGCGGCGGATGAACCCGGCAACAGTCGGTGCCCCTGCTCAGCAGAGCGTTATTGCGAAGTCCATGAAAACCTTATTCACTAACCCGGAACAGCCCCTTTAATACCAAGTGTGAGTAGAATATTCACGCATGGGCAGGGTGTGGCGAAGAGGCGGCCACACATCGACCGGAAATCTCTGTCCTGCGTTCCATACCCCGACGAATTTCATTTCCCCACGGACTAACTTTCAGGGGGAATAAGCGAGGTACCCCTGGCAGAAAAGGCGCAATGTCTGATGAAATTTCTCGTGATGCTCGTGTGGACGATGGCAAAGCTCATGGAATTAGCTAGCAGCAGTGAAGTAAAAGCCGCTTCGGCGGCGACGGAGTGTATCACATCGGGTCGGATGTGGTCGCGGAGTGACGAGATCGAGGATGTGAGAGATAAGGCCCGTAGATCGGCAGGTGTGTGCCCTACGGCTCACTCGTGGTCAGCCAACTGAACTCGTGACCCTCGTTATGGATCTTAAGCTCTAGTAGGACAGCCCAACTACCACGTCTTAGAAGCCAACGATAAGCCCATAGGGCAATGTTTTTAAAGGAGCCCCCGTTCGTTTCGGCCACAATTAAGAATTGAGTTGATCATGAGGACTATGTGATTTAAAAAGTACACGAAAGGCGCTCAACGGAGTGTACTAGGCATTAATCATCCGAGTACATGCTATAGCTTGTCCAACACTGTGCGATGCGGCGAGCGCGGGTCTGAAACGCACCCGATATTGGTTATGTGTTGGGGTGCCCATCGCGCTGTGTCCCCGGTGGGAAAGTGATGTGCCATCATACAAACGATCGTAAATCTGCTGATAAGGACAGACGGAAGGCTAAAATGGAAAGATTGAGAATTGGGCGACTTTCTTTATTCTCAGAAGCAGGAATAGTCATCCGTAGTGCCGTCAGTTAGTAACAAATAGTTGCACGCTGCGGGGAAATCCCCCCACTCCCGGAGTACCCAGCAAGTTAGGAGGGTGAATCCCGGTTGGGCTCAGCGGACACATGGTGCCGACCAGTATTTCCGCATTTTACGGGACCCATACAACGCGTAACGCTTGACACTGGAAACAATAATAGATGTGTCATGAACTTCTAAAGGTCAGTTCTGTCGTCGATCAGTGCTCTCCGCGATACCCGAATGCGATTCTAAGAGTGCAGCTTTCCCTAATTTGCTACGCGACGTATAAATTGGCCTAGATTGATGGGTGGCGTAATGAAAAGTTATGCTGTTGGTTCGTATCCTGTGTATTTCGGTTCTTCAATTCGCACAGTGATTAACGGCCCATGACTGATGGACGTGGGCGTGTAGTATGGGTATACCCCCCTCAATCACCCCGAGTGCACCTTCGTGCGAGAAGCACATCGCCTACATGATTGGGTACCCCCTAGCTAATGACACCTCCGGCCGGTGCGGCGGAGTCGTAGAATGGGCCAATGATTCATCCCCTTGTTTCGTCAGTTCAGGTCCTGTGATGCACCGTACCTGCCTTATCATTCTCGAAGCCTGTTTAAGTTTCGTTTGCGAATTCTGCGGCCTGCTCTGATCCGGGGAGACCTTCGAACATGTGGTACCGAGACTGAGGTGAGTAGTTCAACCATTTAACTGGAACAGCTAAATGTCGCTTTCGCCCCTTACTTCTTGTATCTTTCGTGGCGTTACCATGAGGAGGGCATTTCTGACTGTCGCTTGGATGGAGGAGTAGAATAACCAGTACCCTATTCTGGCCCTGTCAGCGGCACCGGAAACCGGGCCGCACGTGTGTTCGCAGTCATTTGTTGACGAAGCATGCGTCCAGTGAAACGTATCAGGCATAACTTGCAGGGTAGGAAAATAGGCACTCGTAGCCTAGGTGCAAGGCGTTTTATGGCGCTAGAACTTAGAAACGAAAGATCCGGAGCTGTCCGATAACTAGTTTAAAGAATCACCATCGGGGGATTGCCAAACGATACTACCATTCCTTACACCAGTGAGGGGGCGCTTAGTGGGCATGGAGTTGACGCGGGATGCGCGGGCCAACAGATTCCAAAAAGTGACGCTATTTAAAGAGGTGGGCTATGGAATCGGCATGCTTACAGCTGCTCTTCCTCCTGTAGTAAGTATATGCGACCGATGGAGGTCAAAAGGTCTTGATTCGTCGGTGGCCGATGTTATGCGGTGAGATACCTCCCAACGGCGTTGATAAAGGAGGAGGCTTACCATTACGCCCATGTTCGAGCCCCCAGCCAGACATCGGTACCAAGAAGGGTAGTTGGATACACCCCGTTGCCACCAACGAGTGTCTTGTGATTGGCCGATTTCACCAAGGGCAGATCGACCTGGCGTGGAATTCCCTTATGCAACAGAGTCGACAGTTTGGGGTGTAACAATTGTGCGTAGGCCCAGCCGTCGAGTGGTCCAGGGCTGGTACTATACAGCTAGCCGTACAGAATACTCGAACATTGATCACCATGTGACACATCCGAATAAAGGCTAGCTACTTCCGCACAAGCAGATATATTGCCCCGAGTGGATTCCCTGGGGTCTCTGAGGTATGGGGATAACATACTTTTTAGGACTACAGATAAAAGTCTTACATGGAAACCAGCTACGCGTGGTAAACGGATAACGCCACCGGATGTTAATTGGCCTCGCGAGAAGTTTCATATGCACTTAGGGGTCTTAAGCCGTAGCGCTCGGTTTATGCGGCATTGCGAAGTCTGACGAGGCCATTCGACAAGTCCAACAACTTATCACACTTGGTTTGTGCTGGGCTGTGAAGTCTGCAATTGCAGGTAACTTAGCACTCCGTGATCTACACCCAACCGGCCGTACCTCTTGGGTAAAGAGACTGACCCGGGTGTGATATCTGTGGTAGCCAGGTGTTCATTCAAATAAAAATTGTCCTAGCATTCCGACTCTAATTTTCAAACCGTTGCAAAATTCATCGTTCTAAAAGCAATAGCTTGAGAGGTCCTTTTTTACGGGTCACTGCATCAATATTCTTTCCTCTACCACTCAGTTGATCTTAGTCACGGGTATAAAATATCCCTACTGTACTGTTTGCCGGGCGCGACGGTATATTACCCGTGGGGCGGCGCCATCCGATAGACTCGTATATATCAATCACTTCCGCGGAAATTTTCAGCGTGAGCCAATCGATTGACACAGAGTCCGGCACCGGGGTGACGCATTGAGGTCCATGACACTCGAAACTTGGGCTACGACAGGCGCGGGACGGCCGGCTCGTTACTGAACTGTCAATGGGGATCGCGTGCTTACGGTGCGCGAAGGATTTATTTGAACGAAGGCATCTTCTTAATTGTCTTCATTAAAATGGCCTGGTATATAGTTCGCTAGGCGTTTCTACAGTACGGGTAACTTTCTCTCAAGCAGGAACCGCAAACGTCGATGCTGCAGTGGCATTACGGGGTGATCTTAACATCAAGGAATATCTCCGGTGATTCGACACGTCTCCCCACTTAGCGCGTGACCTCTGACAGGTACCGACTGTAAAAGATCTACGTGTTATATTCAACATTATCCAGCAAGTCGTGGAGTGCGTACATGTTATTGTTTGTGTACTAGAACACTACTATGACGGGTGGAGCCATCATGGTTGACACGGAAGGATAAGGATTGCGCACCCATCAGGAACATGTACTAGACACTGCGCGTTACCACCATAAGCCAGTGCCAAGGATATTGGAACGCTAGGCTTACAGTAAGGCCACAAAGATGAGACTCCTAGATCGTCTGCCGTAATATAACAACTGTACTGCTACAACGACCGATATGCGCATGGCATGGATGCGTAGTTTTCAGGGCATTCGGTATACCGGAGCTGTGCCGAAATCACCGTTTCGGCCACGACGCTCACACGATGGTCTGTGAGACAGGGGGGCTCGCAATCTTCCCCATGAACATGGCGTGATTCAAGAGGAAGCGGTGGCGTGTTCGTAGGCGGGGCGCTTTTCATTTCACGAGAGTAAGACAATAGCAAAGTGACGGCCACGATAAGGGAACTAGAGAAACGAAATTATATTACACGTGCAGTCCGGATGGCCTTGCTGATGTAGCTACATGTCCCACTATTCGCGTTGCTACAGGGGGTCTAGGCGTCTGTCGGAGATTCTATTCAGAACATATGTACAACAATCGGCTAGGACCCACTGGCTAAACGCCTGTGGCAGAGTCTCGCTTTCTGTCAAGTCTACACTAGTAATAATGGTCGCGACTGTGTGCTTAAGCGATCCCGGGCGTATCCGATATGAGAGGTAAAGGTATATTGCTCGTCCCGCCCCCATCTAGGTGCGCGTTTTTCTAGATGATTCAGACCCTCTAAGCACCGACGATACTAGTACAAGAACTCTCCATGGTACCCTCATGCAGCTGTGACGTACCGTGTAAGTATCACTGTATAACTACGATTGGGTAATGCTCGTGTACCTGGTCTATAGTTTACGTATGGCACGTGCCAACCGCGCACCTTTTAGGATTCGAAAAGGCTGCGATCGCGGATGTGCTGGCTCGCTTCACAAAGAATAGGGCGCCGTATTAGCTCGCGGCCGGGTTGCGTTCCCGCTAAGTTACTCTATGCACGCTGGTATAAACTCTAGAGATATAAAATCATGAGCCCAGGGCGGGTTGTAAATATCAGCAACGTAACAATTGTGTGCGTTCCTTGGTATCTGCGCAATCGCGATTCTGGGTTACCGCGAGAGCCCCAGGTTCCGGTTTTACAAGTACAGGGCACAAGAGAGATACAGATGAGTGCACGCAAGATGCATTATCGCCATAACTGAAATGGAAGTTCCTTCCGCTAAAGTTGTACCGCACCGAGAGAAACCATTACTCCAAGGACGCTACAACGGGCTCATCTTCCCGTCAGCGGGTATGCAGTATACTTTACGCGGCCGTCCAACATCCCAGTCTATACCTAACCTTAGACATCGTCTTACAACAGCCGGTATCCCTGTGACCGCCCTACGTACGTTGTGGGTGGAAATCAAAAGACTAAATCAATGGATTTCGATGTCGGAGTGACTTTACTCCATGTGAATAAGACCGGACGAACGCCAACTCGAATTGTACCCGGCTCTCCTTTATCGACAGATGCGTCAATACACAGCGAGATCTATGCCTCGAGCAAATCCGGACACTTGACGTCTGCGATCGTAGAAGGACGGTTTTGTTAATCGTACAAACTACCTCCAATATAGCCCCTCGTACTGTTGACAGCGATACGGTGCTATGGCACTAATCTTCACTGGCGTTTATGGGTATGACAGCTTGGATCATTTACCCCTGACCACTCTTACATACGGAAGACAAATTCCAACCAAGCGCTGGATCTTCGCCAGTGACACCAGAATAGTAACCGGGACCACACATTCCTCAGCTGAAGGAAAAGGTAGCAAGTCACTGGAAGGCCTGGGCACAGGAACGATTGCCAAAATTCTTAAACGAGGCACGAGTAGTGATCCTAAGGCACGGAAACAGCGCGTGGCCGATCTGTCGTGCACCTTGTGGTACTTTTCTGGACGAAGAGCAACGTGTATTAACTCTTAACGCTCTTCTGACATGGCTCACAACGCAACAACGTACCGTTTAAGACTCACGGACACCTAACGCTTCCAACCCCCAAGTATTCACGATGCTCCCTCCGTCGTATACCACTCGTTAACTTGATAGGCTTGCTGAAAACAGTGCTCAGGCCCGGTCGGTCGCCTGTGGTAGCTACCTTACTTTACAGCGAATCTAGCGATAAGTTACGTTCAAACAAGACTGACTTTAACGCCGACGGAGAGTTAACCAATGGACCTTCCAGCGGCGCTGACTGTTAGGTGTGCAACTCCCCATGCCAATTAAAACCAATGGGCCTTACAAAATATGATCTGAATGTCCACATTAGTCTGGGAAGAGTCATATTGTGTCCATAGACCAACTTATCAATAGCCCCAGATACTCCCTTGCGGTATGGAGCTAGCATAGTTGCTTTAGTTATTTGAGAACGTGAACTTCCTATTTGTTGTTTACAATTCTAATCGTCTCCTATGCGAACACATAGAGTCCTGACCTAATTCGTTACGTGGCTTGGAAGGTTGCACAGGTCTATAAAGCCGTAGACAGTGGTCCAGATCGTCTTTGCGTTAATTCGGGACAAATCCCTTCCAGTTAACGTTACCACACGGGAGCTCCTACACGAAAATGCTCTTGGGTGTCCTATAACCTGTACATCTACCCAGGCTCGTCGCACCCCCAGGGAAAGGCCACATCTGCGAGGGCTCTGGCGGACCGTGAGTCTTTATTCTTACTCCAACTCCCCCGAAGTAGGCACTGAAGGCCGTTCGTGTGACAGTTCGACCCAGCAGCTCCGCCGTAAAATGCTACAGAATGAGTGACCCCCCCAGTACGGACACAATAGATTGTCCCTCGTCCACCGATATGCGACGCAATTATGCTCGAGCACAGTTTGCATACGATGCCTACAGATGGGTACCACTTGGGCCGGGGCGACTTTCGCCGGGATTGCCGAATATACGTAATGCCGTCATCGGGCCATTTAAAACGGGGAGACTGGGTGGGGAACAGTGAACCCTGAGGCTAGGCGCAAACATTGAGGGGATCGGACCGTTCAAGCCACGAATCCCACGGCGAAGATATCTAGGAACATGTAATCTGACGGATCTCTTACGAAAATCAGAGAACTGGTGCATCAGTGTCATGCCTTTTTAGACATCATATACATGTCTTAGCACATGGCAATTGGGTGCACAACATCCTTGAGTCGAATTCCCTACCGGTTAAGGGGACGTACAGAACACAACATAGGAAGTCTAGTTCGATGACGATCGAAAGCTCGTGCAACATTTACATTTCACGACGGACTCATTAACGTTGCCCCGGCGTGATATACGTCTGCCACTCGGCCCGTCGTACTAAGGTAATCCACTTGAAAGAGCAAGGTCTCTTGCAGGTGACAACACGTGCCTTTTCCGGTACTCAGGTGAATATATCTCGTCCAATGGGCCTCGCCGCAACTATCACCCTCGTTATCGACGCTAGGACGGTTGGGGATTTCTGCATTGGCTCGTAACTACCATATAAACTTTGCAAACCGGATTCCTTGCGTAGGGACCTTCATTGATATGGAAAGCTGCTCATCGTAGGGTATTTGCGCCGCGCAGTTTAAATGTCTTAATGCTGCGCCTCTAACGCTGTCATAAAACGTTTTTGTGAATAATAGAGACTAACTTCCGCTATTTCAAGTGAGTCTTGCTGGTCAGAAACAG . PASS SVTYPE=INS GT 0/1 0/1 +20 900000 . C CCCCGTTTATGAACTCAGCGCCGAACAGAAAAAATAGCCCCACTTTAAGTCCGCTTTAGCGACTCTAGGGTCCGAACGCGCTGTTTCGTACATGGCACGTCGGTAGGCAAGAACTCCCGTCCTCAGATGAAGATGCGTAATATCCTTACGTATTTTGGAACTCAGGCTGCCGAGCATCTTATTGGGAGACTCTTACCACTTTGCCCGTAAGCAGGGAAACGACATTTGATAAAGGATGGCAGGGAAGCTTTTATGCCCCTTTTCCTACTACAACGTCGAATGTTGACTTCCTGGTTAGCGTTGTGGCCTTGTACTGACCCTACTAGGGTTTCAGCTGCCTAGAGGACATTCGACCGACCCACGACCGCAGCTCGCGGTTCATACACGAGAAGCTACAATCCGCTTAAGTATTTGTTCTTTTCGTTCTAGGGCCCGCGGCACCAAGGAGGCTTCAGAAAGAGAATAATTACTCGATCGTCCCGTAAGTAGTGTATCGCTAACAGGGCCTGCGTCGTCCATACTAAGGCAAGGTGCTCCAGCAGGGCATAGGAATTGACCGGCGGGTAACATTGGAGACAACATGTGATTTGTTGCTTAATCTCGGTTAACCCGCCCCGCTGTAAAGGCGAGACGGCAATCATGAATTCTAGCACGCACCCCGCCCGTCTCTGTCTTCAAAATGTATTTTTGGCAACGAAGGATCAGCCTGTCCCGAATCGACACTGTGTTCCTATGGCGTAAAGAATTCTGTTCCTGAATCGCGGGCGCACCGTAATTCTTACTTTCACATCGAATTGTTAGATGCTGACGAGCAGAGCGCAGTGCGGCCGGGCGGAGATTGCAGGGCTGGCAGAGCCATTGGCCGTTGATGGTGTTTAGACGCTAAGCTAACCCTATGCCTCATGGATACTTGCTACACAACAGTGTCTGCGTAGGCTGAAATGGGGACGGCATGAGACCTCAGTGTCAACACAATTTGATGCACTGGGTTTTCTGCAACTACTTTACTACGGCTTTGTCCTTAACGCGTTAAGGGACTCCATCTCATCCGTATCATAAACTCCGTAGTGTATTGGGGCCAAATCTAGAATACGTACCGTCGACAATGCTCACGAGGGTTACTCAAAACTCGGCGGGGTGCCTCAATCCGCGTGCCGTGAAATGCCCGTATTCACGACGACTAAGCACTTAAGTCTCGGGAGCTCTGTTGCGTCTCGTCTAAGGGCAGTCTTGCTTCCTGTGTCTGCAAGTTCCTCTCTAGTGTTTAGGGTGCCTAATATACTCCACGTGTGTCTATGGACTCCATATGGTAAGTAATGGTGTTTGATAAACCCCTGGCCCTTTAGGTTCTACCTAGCCTAACTTCTTCCTTTGACTTTTACCCCCATTGATCCATGTTCGTCGAAGTGGCCGATTGAGGCTGCCGCATGGCCAAACCGCTAACCCGATCGAGAAGGTTGCAAGGGCGCATCCGCAAATAAACCATGGTTGCTAATTGGGGTGCAGGCGTAGAATTTGTCGGTTCAAAAGGCCCTCGACCTGCACAATGACTTGCGCTCGTAACTTATGATAGGGCCGGCATGGGATTATTCGAGGGACTCCTCACACTCAGAAGTTTACTCCCGGAGCACGACTTTACGAGGTGTGTTGCTTTATGATGGCATATAAAAAAGATGCACCAATCACCAAAACCCAACTATCCTTGACACGATCAGTGCGCGACCTACGACTACTCTAGTGGTACGACTATCGCGATGGAGGGGATATTCGTATATTTGAAGTTCATGTATTGATTCGGTTATGGCGTCTCCCTTAGTGTTTATGGACTTCATGCGTGCCCCTTATCCGCCCGCAGGCACCAATCACATTGTGGAGTTAGTTGGAGCGAAATTGGGTGGCTGTACGGTCAAACTAGAAGCATACCTTCACAAGGGCGTGGCGCTATGGGAAGTGGACCTGAGGGACACGATGGGTGAGATTCGGACACTCTGTCTACAAAATTAGGAGGTACCTACTGCTAGCGAGCTTCAAAATTCGGGAAGAGATCCTCGTACCACGTATTAATGAAGAGCCAGTGGAGCGAAGAAATTATCGCAAGACCGACCCTGTGCCGGCAGATGGACGTGTTAAACATGGTACATTGAGCAGTCCGACTCGTTGTATAGTTACCACGTGTGAGAAGACTTAGCTCGCAGCTAGTGGACAAGAACTCGGCCGAAGTTTCGTTCCTGTATTGCGCGTGTCCAGGATGTGAACAGTCCAACTTCATTATTTTATTCTGACTTGACACTGGACGTAAGTCAGCTGCTCAGAAACCGGAGTTCCCTGCCTTGGCCTGGGGGCCCCATTTGCGGATGAGCCCACAGGTCTCGTAGACTTAGGTGACGCCGGGATCTGCTGGCCTTATGTCCCTAGAAGCTTGGATGACCGGCCCACGGCAATGCGTAGTCAGGGAGGTATCCATGACGTGCGTGAGTCGGGCGAAGAGGGCCCCACATGCACCTAGAATAGCTATGTGTGTTTCTCGGGCGGAGCCCGACGTCGTCCCGCTCATATCCAAGTGCTTTTTCCGGGGGTTAAGCGGTGGCTTGGGCACAAACGGTCGCCTCCGCCCGCTTGGTCTCTCAGGTATTTCCGGGGGCACTCATAAACTACGAACGCGATCTCCGATAGCCTTCAGTTGTGGGGATGCGGCTAAATCCAAGCAATTGCGACGCTTTGGGTGTGGTGGGGGTTACTGATCCGGACTGCAAATTACTAACTCCGTCACCTATCAACACGTCTCCCTAATCTGTTGGAACCTCGCTCTATGACATCAGAATGCGAGCGCGGACATGGGACATGTCGGGACAATCTATTCTGCCTCTCCGGTACTGGGTACGATAAGCGCGACACAAGATTGTGCTCTTACTTCGCCGTGTTACCGGGTAAATCGCCGGGATGCTACTCTTATATGTGCCTTCTCACCTGAAGCCTTGCGACCTCGAATGATTTGGGTGTGAGTAAGCACCCGGGATCGAAGCTGGTAAGCACGTCACCATGTTAGAGATACTTGACCGACGATGCCCTTCTACGGCTCGGTTCACGGTGCCCAGCGGGATCCTCTTATCCCAGCCGGTGCCTAGCCGATAAAAGCTCACAAGCTTAAGGCTCTGTCAGGGGAGATGTGGGAGAGGCTCGATGAGAAGTCCTAACGACACCAGAACCCCAATTAGCACACATGGCTCTTCCGGGGACTTGGCTCTCGTAACTGCCTGCAATGTACTACGTCGCATGCTCATGTACCAGACATTATGTCCGTCCTTAACAGTCGTATTGGAGCAAGTTGTGAGTACAAACAGTACACAAGCTGTAGGTCACTCCCCCCACGTCTACCCTATATACTATAAGTCCTTGTAGCCAGGATGAGTAGGCCCCGTGTACCTTATTTGAATGCGCACCCGTGACTTCTGGTGGAGAACTTGGTCACGTCGGGTGGACCGTGTACGATACCCCACAGTGCCCCAGGAGGTATGGAACGATGCTGCCCTGAAAGGTGGAAGGCCGGAGTTTTTGTAGTTACAAACAGTACTCAGCGCTATCAGCAAGTGGACACGGAGAAGTAATTGAATGACCGCCTAGCAGTGCTCCGCCTCCGGGCGGCAGCCCGCGTGCCTCAGTCAGAGATCTCGAGCACGCACCCTTGCTGCTTCCGACTAATGGGAAGAAGTGGAGATGGCGACCCCCACGCGTTATAGTCCCAAGGTTGCTTCCAGGAGCTATACCCGAACCTTTAGGTCTAGACTTGTCGAGTTTGCGACCGTACTCGCTTTGTATGTCGACTTTTTTGAAAAGACAACCGTGGCCCGGTCACTGTGTCTCCAGTTTGGCGAGCCGTAGTCAGTGATCGCGCTGCTCGGGATCAATTATCTCCAACGGTCAGCAGATCTACGGAGTCGGTGGCCGGTATAATGCTGGAGGCCGGTGTATGCAGGAACCTAATAGTCCCCGAGTGTCGATCTGTACGGGAGTCACTAAGATAAGGCAGAACTGACTATCTCTCCACCGCTACGTAGTCCAGTGCCAAGGTGTGGTCATGGCCCACATAAATCAAGGATTTGTATGCTAGAATTACGCGATCGAGTGACACTCAGAGTGCACTGGCTAAGGACTCTAGCTTTGTAAAGACAGCATTACATCAACACTCGTTGCATTCCTAGACTGCGGTTCCTTCGGGATCTCCCCTTGGTACTTCCTATATTTCCTGAGATGTGGGCGCAAACAAATGCCAGATCCCGCCTGTAGGCATTCGGGACGGGTACTACGCGATGACCATATCGAGATTGAATCTTACGTATCTCCCTACAAGTGTGGCTTAAGGGGTTAGCACCGACAACTCATATAAAAACCAAGTAAAGAGAGTAAACACAGTGCGGAGTAGCCGTACTTGCGAAGCGCCATTTGGGCGCGACCTTCCGAATTTGCATCCGACGTCGGTCGTATAGCAAAGAGCGATTCTGAGCCTCCAGTCGCGGCCACGTCGCCGCTTGGCCAATGTATACCAGTTGTGAATAGGTCGCGGAACGCTAATGGAAGTAACCCCTCCTATTACCAACACGCCTCAATCGTACCACCGGTACCCACGGCATATAGAGACTATACGGCGTCGCGGCGGGCCTCCTCATGCTCGTATGGACTACACACCATGTCCTAATAACCTTGGTAACATTACGCCTTTGAGGGGTTCTTTATCTCCGATTTCGCGGTAGATAAGGCCACATGACATTTTCCGTTCGAGCGGACACGTGTCGCCTCAGTAGCCTATTGCCGTCGCCCAACCTACGCCACTGGCTCATGCCATGCCATCTCATACAATTAACTCCCGACGTTCGTACCAGGTGTACCAGGGGGTCCATACTAAGAGAGTGTGACCTCCAGATTCTAAAATACTATGTGAGGAAGTCATGATTTCCTCTAGTCATTGTGGCACCGCTCGTACCGTGAATCATATCAGATAAGAACGATCAGTTTGCGACTGTTATTCCGAGGGTACAGTCTTTAAGACACCATTCGGAAACGAAAAGGGACTAATGGATGCCGCGAAAAACCTAAAAAGGAAACAAGCTATCGATCTGTGGCGCCAAGGAGGGCGGGGCCCCGCATGACTCGTCAACTCCCATAGGCACCGCTCCGGGCCGGTAGCGACCGGAAGGCAATTGCTACCCTATCATATAAATGATCCTGGTCATTAGTTGTGCCCCGTATACTTGAGTCAAGTATTCCGTCGCAGAGACTACTGCTCATCCGAGACAACTTCTTCTCTAAGCGACCCGGGCGGACAAATTCACACGCAGATGGGAATTACACTAGGGGTATACTCACCCGGGCCTAAGGAAGGCACATGAGTGGGGCGGGCTGATTAGCAATTGTATCAAACTAGGGTCAGGCACACATAATGAAGGAGCAAATACATTGCACGGATATAGCCTAGTCGAGTTCGACGCGGAAGAGGTAGGCGAAATAAACTGTGAAAATGGGCAACACCTCACGAATGGTCATGAGTCAATGTAAAATCTTCGCGGCTTACTCGGCCTATTGCTATCGTGACTCCCAGGCCCTCAGTCCACCTCTCGTCAGATACTAGTTCGGGAGGCTCGAGATAATTGACCCTCCCTAATTCAAACTCAAACGAACTCACGTACGGGTAGGGCACCTAATTCGAGATGAAACATGCCTAAACGCCTCGAGAATATGTCTGTTTTGTACATAGTCTGTCGCTTATTCCACCACTTCAATCTGAAAATAGCGGACTAGTCCCGAGGGCCCCGATTTGACAGGTGGTTGAGAAGATCAAGTTGCACGCTAGCACCAGACCCTAACTCGCAACTGCTCTGCCTGATAAAAAACACATGAATCTGCGAACCATAACCTTCTTTGCCATTCTTTGTCTGCGGTTAGCGATGGGGGGTGTAAAACCACCTGCAGCGCGTCCCGATGATAAGCTATATGGGTTCACGTGCAATCCCAGAATCCTTTGGGGGGTGGATCAAATTGAAGCGAACGCAGCGTTGTATCGACGGTGAGCCCGCACATTTGAACTCGTTCCTCGGGTTCTTCGATGAATGTGGACTACGCTAGTTGACAATGCCTGCAAGTCTCCTCTCTCCCCCACGTGTAATATTGTACATAGTCAAGAAAGCTACATGCACGCCGACGTATCTTCTGTGCTTATGGATCGTTATAAAATTTTGTACTTACAGTGAAAATATGAAGGATGAAGCCTTAGAACTCGCTGCGTGAGAGAGAAACCCACCTATAACAAGACGCACGTGGCGCACATCCGTCCCCAGTGTTCAGCGACAGTTTGTCTAGCCAGTGAATCGGATCAGGCGGTCCTAGAGGTCTAGGCGACTTATGATCTTAGTCAGTAACCCCAGTAATTACCGTGATTACCATTTACAACGGTTAATTGGGTTGGTCTATGGTAACGCACAAATTACTCGTCATACCTGCTTAACATGCCTTCGGGAGTTAACGCTGTCGGGCGGGGTCAGCTTACATTACAGTAATCCGGCAAAAGACAAACCAATGCATCTCAAGAACCAACATAATAAAAAGCCTTATCAAATCTGGATCACAACTAAACGTATCACAGTAATATGTATCGCGAGTCTAGGAACTTGAGCACCCAATCATCATCCGTGGCGTCTCCGCGGGCTCTGAACGAGAAAACTGGGCACTCCCGGCTACTTTGAAATCAGGAAAAGGTCATCTGTTAAATGTCTGTTCACGATAATAGGCTATTCCACTTCAATACATGAATGACTTAGGATAGATATTCCCCTGGGCACGATGTTCTTATGGAGTGCGGGATTTAGTGGATATTCACGCTTGTATTCAGTCCCCTGTCCCATCACCTTTTTATTTGTCCTCCGCCCGGATTCGTTTCGTGCACGGCCAACGAGGAGCTGTTCATCAAATCTACCGACATTAATAAGTCTGGCCTATATGTCGTCCAACTAGGGACCCCTTTCAGAGTAGGTGGAGCTATCGTAGTCATCAAGTCACAAAATGAGTTCCTTTAAGGTGGCGATGTGTTGGGTGCAGACAGTATAGATAACACTCGGCATGGCTTTAGTCCCTCTATCTCGGATGCGCGCATCACAGATACCGCACAGGGTCCCACCTTACATGTTCGGTTGGGACTGAGTGGAAAAGTTGGACCCTAATGGTTGCTTCCGCGAGAACAGAGACTTGAAGCAGTCAGTCAGGGATTCAGTCCGTCAGATAGGGGTGGAAGTATGGCCGGCGGCCATTTGAAGTCGGCTAGCAGCAAATAAATTGCGTAAATATGTTGGTGTTTGGGACAAGGAGGCACGGATCCAGACGTTACTGAGTCCCCGAAAGCGTTACTCACGGATACACGCCATACGCTCTACTAAGAAGAACCATGCACGGACCATTCGATACAGTCTTTCAAACGCCAATGAACCAGGAGCCGGGGGGATGAAGGTGGGTTGGAGGCATCGGAGTGGTTGGGAACTGGTAAACGAGAAGGCCTAAGAGTACTCCCAACGCGGTGGGTAGTATGTAGGTTGGTTTAAGTCGCGTTATCTGGAGCCCGATACAGAAGACCATCAGCTAAGAGTGGTCGTAAGACAACAGATAATCCAGGCATACTAACACCGTTTTATTAACACCTAACCCGTGCGCGGGCAATGATCTGTGATTTCGGCGGAACCCTTTAGCAATCACTCGAATGCTCCCCTCAAATTTGAAAGGCATGACCTCCGTTGTACGCCCTGGATTTCTTAGGGATCGATTAAATTGGAGGCGAATCGTGTGTCTGATCTATTGGCCAATTTGATAAATCGGGACAGAAAACCCTGGGCAGCTGTATCCCGGCCAACTTGACTTTCACCTTTATGCTATCAGAAAAATCGGTGAAACTGAAAGTCTCTGAAGTTCTCTGCAGTCATGCGGGTACACGAATGTGAATATGAGCTGTCGCGAGTTAATAGGACAGGCAGAAGCGCAGGTTGCGTCCTAACAGGAATACTCTTAAAGTAGGTGCGAATCGAGCAACGTCATCGCGTCAAGCGCGACCGCTTCAGTTGGTTGGAGGCTGTCGGCAGGTTCATCTTGCCAAATCGAACTAGCAGTGGCTTCGTTACGGGCCAATACCACCTCGAGGAACCCGGGTAATGAGGTACAGCTTACACAGGCAACCTGACAGAATGGATGTTTGACCTTCTATGCTGTACGTGTTAGCCCAACACAATTAGCAAGATTGCACCGGCGCTAACAATGTTAATGAGGTGTACTAAAGAGGTCGTACAGACAGGTCATGGGGGTAGGCGTATTTTCGCGCAGAACACGGGTCTATCCCATGAACGTACAGGCAAAATATTCGTTCTAGGAGCTGTGGGTCGGTTCCGTGGAGAAAAGTCGCAAGGCTATGTAAGCATTCATGCCTAATCCTCGCAAAAAGTGTGTGGGATTAGAAGCGTGTCTGAGCAGATGTGGTGCGGGATCGAAATAAGTAGGTAACTACCACAGCACACTATTCCAAGCAATAGTTCGAAAAAGGAAGACAAACCGATTCGGTTAAACTTGTGGCGGTCCTTTATTGCGCTAGCGTGCACATACTTATAACCGTTCCTTGCTAGATGCCAATACACGATATTGGCACATCAGGTGCTTTCACCCGAGACAAACGGCCTCTGCTAGCAATCCCGGGTCGGTAAAAATAGAAGACGAGAGGACGGCGATCATATCGTGCGAATAGTATCAGGCTTCATATGGGCAGTTCGCCTCGAGGACTACCCTCGTCGAAAAGCTTTACCGGAAGATGCCAAACCCGGGCAGCGGCACCAGGCTGTTACCCGTACTCCTAATAGCTCGGCTAAAACACGGAGAATGAAATACCTGTACCAAACGCACGTTGAGCTTCATCCACCTCTGGCGTGTGTACTATCCTATAGCGGATTTCGCCGGAGTTGCCTTTTCTCCTTGAGTGTTGATGCTGCCTTCTAACAAGCGCCTTTGCACCCAACATCGACATTTAAACTTTATTATGGGGTTGGTCCTGCTCCGTGCAACTGTCCTCTCTGTCACCACTATATTAAACATAGTCTGACCTAATGCAAGTTAGTAAGGAACAAGAGCAGCCTCATAAAGACTTGGCGACGCGTTGAGACACATATTGGGTACTTTAGGGATAATAAGTGTGAGGTACGAGGTGCGCGGACATTATCTTGATGCCCTTCTTGGAAATGTCGTATTTCAGGCCCCTGGTGCGGAAGAACTTTGGCCGGGTTTACATAGTTTAGATAGTCCTAGGTACATCAAGACGCCAGTATGAGTCCGCGAGCCGGTATGAGTCATATACAAGCCAAAGGGCCGCCTCCAACTTCTGTATCCGTAATTTTCTCCATAGGGCTCTGACCAGTATTGACCCCAAAATGTGGGCTGCAGATCCAAAGAGTTAACGGTACTACCCGAGGGATCAGTCATTCACTACGGTGCGCCTTGGATGGGATCCTACCGTTGAATTCGTAGCCTCCTGCGCTCCGCTAACCCTGACAATATGTGCACTTCGCCTGGACGTATTGACACCTGAAACGAGCACTGAGCGTAAAGCTAGTTGTTATACGTCACTGCACCATGTGGCGGGTTATAGCATCCTCCCATTTAGGTAATGCGAATCTTCACAGACATGACGGGGCATGTGGACTTACCGGTTACTTCGGGAAAACTGGCAGACAAAGGTTGGTTATAACCTACCAGCAAGTCATAATCTGTTTCAGGAATTACGCAGTTCTGCCGCTCATCCTAAAAATCCACCGACCCTCGCACGTGCCGAGTTAATCTACGGAACGCATAAGAGAACGGAAGCCCAACTGGAAGTTGGACAATGCCATGAGCGCCCTCGGACCACCCTCAGAGAGGTAATTTAGGGGAGCTAGGTAATGATCACGCTTTTCAGTGGTCCTGTATCGTGCATAGGGAAACCACTCTGGATAGTGCTTCTAGCGAATCGTCTAAGTACCCCATCCTTATAGCCCTGCCAAAGTGCTGGTAGTAGCTATCCGGATCACCACGTTCGGGGGACGGGGCGTGGCTCGTCCGTATGCTGGCTTCGCCGTAGCGCAGTCCGAAAACTGACAGACATAGTGCATTAGCATTTAAACCACCTCGAATAAGATTTGGGCAGATAATAGCGCCATCGTGTGCACTTGTTGCTCGGTGCCACCTAACCCCGAAGCTCCTAAGGCGCGGGCCTATAATCGTTATCCCCTACGAAATGCAAGTGCGTCCTTGCTAGAATCATTTGACTCTCCAGGGCCGGGAGTGATAGACCTTTTCAGATGTGTACCCAACGATGGGTTCCTACTCACGTAGATACCAGTTCAACCGCATAACCGTGAATTTTGGTCCGTGTCGTGGACGCCCGGAATGATAAGCCTCAACAGATTGCCTGTTTAGCTGGTCGATTGTGCCGATCAAGTTGACGTGCTAGGCCGGCGCTAAGCGTAGAGGAGAAATCTCGCAGCTTCGATACACGCGAGAACTTGGGCGTCACTTACATAGTCGGAGGTGTCATGGTTGAGCCGGTATCTCCGATTGATCACTCGGGACCAAACTCTATCTTCCTTCTAGAATCATCACGCCGACTTGAACACTGTCGTCGTTTATCACTGATAACGCTTATCAGGTTACGTGGAATCGAAGGTTCAAGACGGTCATGGAGCTGTTTTCTATTATTTCACTGTTAGTTCTTGGATACTGGCGAAGGACGCGCCACTTAGACTGTGCAGTCCCCAATTGGCTCGAGATTCCATCGGCGCGTCTACCTGACTCAATGCGTTACAGTCTTGGCCTGGCGCTCCTACCCCTGCGGCCTATAACGAGGTGGCTGTCCCGCGTGCAACACTCGCGAGCAACATGCCAAGACTTAGGTATAATAGCTTAAAGGTGTTCGCTTCTTGGTAGATAATTCTGGATCCGCGTGCCCACCTCCCTGTGCTACGAAGTTCCGTGAACAATGTCTAGATGTATAGCAGTGTGCAAGCCACCAGGTTCTATGGTGAGCAGCAATACAAGCCGTAGGTGACGTTCGGAATGACCCGCAATTTGTCGCGCCCCAGAGTAAAGCGAAGGCTTGACACTCCCGACTAGTAATCCCATGTGTAGGCCCCAGCACTAAAACATCTCGTTCCTCCTCACTTCCTGTGCTCAAGCCGCCTGGGGTCGAGGCGTAAGTACGGTCTTGATTGGTTGATTTTTGGACAATATGATGTCTCTACCAGCAACGCCGCCACCGGTTATGTCAGTCTCTGAGTTATAGCTACAATCTCAAGAATGTCGTGCGGCTCCCGTGGATGGCAGACGAGTCAAGACCAATAACAGACGTGTGGCACCTCTGGTCGTATCGTCACCCCCAATTGATGAAAATGTGGCTAGAGTTCCGAGGAGGACTTGCAAAACGAGTATCATTGATCCAGCCCATTACTCCAGTGTCCAAGCCCGAAACTGTAAGAGGGCCATTGAAATAATACCGGCTAAGGAATGTCTCGGGCGTGCGGGAATCATAAGGATCCCTCAGTTGACGATTGGGCGCCTCTTTTGCGAGCGGCATCCGCTGCATCGAGGTAAATATGTGTTGGGGACACAAGCCGGATTGGCATTGCCGGAACTTATGTGCGGCAATTGCAAAAGTCGAGTACTAGAAGGATGATCAATTGCCGATGCGCCAATTGAAGATGATCGCCTAAATTGGCTTGTTCATCCTTCGCTCCTGTACGAAGAACTCTATCCAACAGTTGATGGTTGGCAGTAGTTCCGCACGAACAACAACGGGATGGAATTCACGGACATGTTGGTGCCTAAACTAGCGCCGGTTTACCGGACGTGTCCGTACTCATTCCCGCCGCGCCAGCCAGAAAGGGTCGATAATTGCAACCTCTCTCGCAGTATCCTTTGGTCGGCAGAACGCCATGGAGCGATCTCCTATCTCTCAAGGTCAGTTTAAGAATTATGAAGTACTTCTCGACGTGTTGAACTTCCGGTCTCGGCCGTTAGGCTCGCTCGATTGAAGTACAACAGAATTCAGTTTAACCTACTACTCGCCCCAGAGTACTTCCTATGAATGGCTGAACTCTGACACCGAGTAGACAAGTGGTGGATATACTCTTTACGGGAGTCACGTATATCGTACTATTATGTTTCAACGGTGCTTGCCATCCACCACAACACCGGTAAGATTATCAACGCTTACTCTCAATATTGCCCGCGAGGAGGTCTTATCCAAGGTGTAACAATAGTAGTCTGTAGCGTTGAGATTAGTCTTAGAAACGGTGAAGGGCGTTCTCGTGCGCTCGATACCGCTCCCCCCCAATCGTGTTCGGCATCACTAGGACATACAGCGGTCGCCAAAGCCTTTCACCGGTATCGCTTCTCGGGACTGATGCTGCAATACACGCGTAGTCGAAGCAAATTTATGGTGCCCAGCATCTGAAGCAACTCCATAACTTTTACCGTCGATAACAGGATTTGGTAGTCCGCTCGGTACTAATGCCGCAAAATGAAGCCCTATAATGAGATATCCTAAGGACGTAGGGCGCCATTGTTGGTTAATTCCCCCTACGGATTGACGGGCCGCGCCGTCGGGCTGGGGTTCGTATGAACCTAGCTCCACGCCAAGACCTGTCCCTTGTCATAGCCAACAGGACACCTTTCATTATGGCGCTACGCATATGCGACTGTTCCCACAGTACAATGATGTGCTTAACCATCGTCGCTCGGCGATAGGGTATCTTTTAACTATCTTAGACTGATAACGTGTGGGCCGATAGTATCTAAGAGCTGTGAGGCTTGTGGACCACTTAAGCTATCGACTCCCATTGGGGCAAGTGATTACCCGGGTGCTATCCACAAGACCGCACTTGTGTCCTTGCGTCGAATTAAGAAAGCTATAGGGACCAGCTGATATTAGGTGCTGAGGAGTGCTACCGGCCTGTTTCACATATATCAGAACGCGTGCCCTGAACTAAGACTCAGCCAATCAATACTGCGTTGTGGGTGAGGCAAGTATTCTGTCCGGGGATGCTGTGGGGGACAGTATTGATCTATCATACTAACCATAGTCGACATCTCAGGTTTTCGAGCGCTGACGGTACAGACAAATTTAGGGCGCTACGAGAACAGCATGTCGCTTGAACCGACTCAGGCGCCGTAATTAAAGGGAGTGTGCCATGAACTCGAACGCACTCCGTATCAACGCAGAAACCGCCTTACAACACTGAGCGGCGTAAGAATACTCACTCGATATTGATTACCGTAAGGCTATATTTGTATGGGAAGCAAACGAATGACATTTCCTGGATATACAACAGTTAGCTGAAGGCATATGTGATCTGCCAGATTCCAGAAGCTGATGGGGGATCAGGATGAACCTTGTCAAGGATTCGTATCTGCGCTATACAGGGAGAACTGTGCGATTGTTGAGGCTACGCCGCGTAGCCGAGCCGTTGGAATAAGCAGCCCCGTATGTGGACATTGGTAGGAGCATATTCAACGGGCCACTAAAGGTCGCAATTGCCTACATCAGATGAAAGGTTGTTACCGGGCTAATATCATATAGAGCCCTCTAATATCCACCTGTTGTATGAATACTGTCGCAGTTTCATCACGGTTGCCCCTAAAACACTGACAATTAGGTAGCGGTATCGTTTCTCATCTACTCAAGGCGTATCTTGGGTCGCAGGGGCACGCCGTGGTTGCTCGCCAGTTACTTACTGACGGTACCTCTCATTCTTTGCAATGCGGGTACTTGTGTCGTTGAAAGTAGTGGTACTCGCACCAACTCAATCTATCGCCGCTGCGAGACAGTCCCCGAAAGCCTCCGCAGGAGCAGCGCTACCTCATATCCTGCACGATTAGAATTAACTGCCTCTCTAGAAACGAGTCTTACTAGTAGTTGACCTTGATTCTACGGCCACTCGCATCGCGATGATTGAGAGAGTTCCCCCACTCACGAATTAGGAATCATGTTGTAACAGCGGTCCCACTTGAAGGTGAGTCTCCATACAACGAGTACATACTTGAGCAAGCAACTAGATTATCAAGAACACGCATTTGTCCTAGCCTGAACCACTTTTGGTCTCACATAAGACAGCGGGAGAAGCGATTCGGGCGACGAGGCTGTTAAGTCGCACGGGTTGCTATTCATATAACACCTCGCCGTCGTGTTAATGATGTTTATGAGCCCTGGCGGTATGCAGAGCTAATTGGTTTGCATGGGTGAGGTAACTTGATTCCGTGTTTGGTAACGAGCGGCGGTCTACACCTAGTCTCGGCCATTGGAGACTGTTCGCGGGGGTAAAAAATCAATTATACAGACACTCTAGCCTGATATTGCCCAATTTGAAAGAGTTCAACCTTTCGCAGTTTAGTGAAAACTGAGCGGTTTGTGAATATTACCGGCCTTATATATCAAATGGTCCGGTACCAAGCCTAGACATGTTCGGACTTTGTTCCGTTAAAACCGAAGATTACGCATTTCACGACTCTAATTTTTAGAGACTGCTAGACAGGATATCAGCCACGGTGCGTCCTTCCTGTATCGCTACGTACTTGCTCCTCGCCTTCTATATAACGGTACTGGCGAATTCGACAATACCCTAATAGGAGCTGCGACTCTCTAGACGACCAGCATGCAGCTTATTTAAGTCACACAGATCGTAAGAGAGCCTCGCAATGCTCAGGATATCGGCTGCCCTAGAGGATTAGCGGGAGTTGGCTGGCGCTATTGAATGTGTCAGCAATGGCAGCTCCAGGATCGTCCAAGGAGCCGCTGGCCCGTCCCATATGGTCTTCGTATCAGTACTGATCAAAAGGCGCAGCGTGAATACGTTTTCCTCCATAACATCCAGTCAGTAGCTGATAACGTTCTCACCCACTGACTTCCAACAGGGGCGATGGACCTCCAGGCGAGCCATGGAGTTCGACCCCCTTGAGGTATAGTGTAGGAACGGGATAGGGATTAAAAGCGTTGTGGTTTACTCTAAGCAGGCTAAGAGGCATAATGTCAGCCCATCAGCGCGCGGTTAGACCTAGCCGATTGGCGCGTACCAGGAAGCCGTCCGTCAATTTACAATTGGTCGTAGTCGGGATACCATCTTGAAATGCGTAGTCCGTCGCGCTTCGGGGCGGGCTTGAAGTGATCATGTGCACCCTTTAAAGCCATAGCCATACAACGTACCTCGGCTGAGTAGGTTCATTCTCTTGGAAAAATACCGCTAAGATAGAGACACCTAAAGTAGGCTTCTTAATAGGGCATGTGTTTCCGCCTAGCGTTGACAGCATGTGATTAACCACTTGACCATCTGTCACGCGTCATGCTGAAGCTTACCCTTGATACACGGGCCGTTATCCAGACGCCTGGAAACTCGAATTCATCAAAATTCCTCCATTTCTCTGGCCCGACAATCCACTGTAGAGTGGGATCGGTGTAATACCCTGAGTTTTCTAAACGGCGACACCGATGCTATTTAGTATGCCACGCGCTTCGTACTGTTGAAAAGCAATTGGAACTGGATGTCTATCCCGTACTTTTAAGTCGTAGATCCGCATCATCCATGCTAATCGTCGTCATTAACCAATCACAGTCTTGCAAAACTCACACTGGCTGATTCTGTCCAGCGTTACCGCGGTCCTGTCCGATTAAGAGCTCTCTCTGCCTATTTTCAGTTCCCTCCAGGCGTAAGGGACTTGATGTACACGCTCGACGAGTGCGGCTCTCTGTGACTAGAAGTCACTCGGGCTAAAGACGACTAGAGGTTTTTTCTGCGATCTAATATTAACCATACCCTACACAAACGCCCACCGGTTTTTATCACAACCACAGTAGCGGAGACGTAAATCGTTGTGCACAGAAAGTTAGGTAAGTTATCAAAGGGCAAAAGAATTACAGGCCATATTCTTTCAGTGTGACCTTCGAGTGCGGATTAAGTCCGCGGCAAAAGCCTAGGGACGACATCTTAGTAGGCTATCTCCACCCAGTATCTGGCGCGACGTCAGGTGTCAGTACCATGCTCTTATGCCCCCCTTTAGGTCCACCTAAACCTCGAGGTCAGCGATTGACCCATGTAGATACTGGTAGACGTCGGTGCCACTATGATCGGTTTTGTCGTAATTCACGAGCATTTGTCATACTGTTAAAAACAAACTTTGACGACAGTTTGGTGCTAATTTGAGAACCCACGTGGGGCCTGCCGCCGGATGTACGGTATGATCTCACCGGGTCTCCATGATACCCCCATCAGCCTCATGTTCTGGCCCGTCCTCAGAAGCGAGCCCTCAGTCCTTTCTTAATCTCCAGTTACTTATCAGGGAGTCCAGAAGCTCCGGGTCTTCCAAATCCTCCGCGATGTCTTAGTCGACCCTAGGGACACCTAGAGGATAGTCGCATTTGTAGTGTAGCTGTCCGAGAGCAGAACGCTGCGGCAGGCGGACATTGAAGTTACGGCTATGTTATCAGTCATCCTCGGCTTATAAGAGGCTTTGGGAAAGTTGGGTTAGTGGCCCAAACGATGATATGCACCAACCAAACTCTTTCACAGCAATCCCGCAGAATAATTGCGGCGCGGACGGGCGATGGGCCAGCTGCTAGGGTAGCGACAAAAGGACCACCAGCTTCTGTCTGAAGACAGGGGCCACCAAACCACCCTTGTCCAACTCGTATGCCCGAACAAGAATCGAGATCGAATTGTCACTTATCATCCCGTACACAGTAGGTCCCGTCTACGTATTCCATGCGTTGCCGCAGGATTTACACCAAGTTTGGTCGCCGGTCCTCACTCGCTAACTACAGCTGTGTAAAGCGCGGGCGAGGGCGATGGATACGTACCCGAGGTTATCAGGCTGAATTGCTGGTGAACACTTAGGTACGACTCATACGCGGGAACCCGGCAGAACTGTACATTCGCGGTTTTTGTCCTCTAGCTATTTCCAAGAGCTGATCACGAGAAGTCTCTCCACGCACATCGCTGAAGCGAGACCCTCGCCAAGTGTTACTTATAGACTTCTATGCGGCGCCGCAGTTTATACAAGTCCTCGCTCATTTTAGTTCGTGCCTACACTGTCACTCCTACGGTACGCCACGGCGCGTGGTGATGAAAAGGTTTCAAGTTCGTATGCGAAAATACAGGCCATTTAACACGGACTCCGCGTCCGGGCGGGGCCGTAACGTTGCCCGTACCCGGACAGTTCCATTGTGAAGCACTACAGCTTCAATGTTACCAGTGTAACGCCAGCATCAAGAGTTGCAATGGTCTAAGCGTCACCTGAATTTGCTATATCCTGACGAGACAGGCGTGCCCCATCGGAATGGCAGAGGTAATAGGCAGCATCCCCGCGGATCTTCATCTGCCGTCAACAGCGCCGGATTTGTAGGCGGGGCGATAAGCACTCGGGGGTCATCGTTTAACCACCAAATGGGCAGTACAGGTGTTCTCCTGTCGGGCCGTGTAGTTAGTCCGACAGGTGAAACAATCTGTCAACGAATTGGCGCCTACTTGGTCCGCCAAGTGAGATCTTGAAATTACAAGTCTTTCCGGCGCAATCAGGCCACGATACTGGGGCAACACCCCGTTGGGACGACTGGTAGAAGCTGGACTCCGGGACGGGGCACAAGGCGGTGGCGGCATTGAACAAGCACGCACGCTCCTCCCTATACCTACGACAACTTAATCTTGTACCAGACAACCTAGGAACCCTCACTTGACTGCTCAAGCCGAAGGGAACAACCCCCTCCTTGGACAAAGCTTACTGCCAAGGCTTGGTACGTTCGCGTGTCCGTTCTGTATCGGGACCTGAATTGCGTGTGCAAGCGTCATTCGCCATGGCCACTACGGCCTGGTCGGGCACCCAGTGTGATAGTCTTTCATGCGAATGGCCCAGTGCTATCTTGTTCGCAACGTTCTGTAGATAGAAGGCCGTGGAAACTGCGACTATCCGCCGCACAACCTTCACGGGCCCCGCCTCTCTATGGAATACGTGTCTCATGTGCGATATGAAGGTTGCCCTCCATAAAGCAGATAGTGCTGATGTGCACTACTTGGTACTTTGAAACGTATTAGTCTCACCTGCTGATGATTCCTTTAAAGCGGTGCAAACAGCCTTCGGCAACCGGCCACTTAGGCTCGACGGACACCATGCCTTTCTGACTTACAAAATGACCACGCCCCTACGACAGCTGTCGTTACCAGGCATGCCTTAGCTGTCAATGGCCTCATCCTGCCTCCTAAGGGGGTATGTTCTCCTAGTAGCCATGTCATAAAACCCCTGCGCGAACCGGGTTATCTACGAACAGTACGAACCCGGCGCGTTTTGGCTAAAGTGGGGTTTATTCAGGGAGCCCGACATACCACAACAGTAACAATAACACACTAGCCGTTAGCAGGGTCGACGTGCTCCCGTTCGCGGAATTCTGGCTGAACGTAAATACGCACCTGAGCGAATTTTCCACGAACACTTTTACATTTAACCTCGCAAGAACCCTCCCCATTAACGAGCTGAAACGCTTATAAGAGAGACGTAATGGATCAGAGACCATCTCCTCCGAGAAAAGTCTGGGTGAATCTACGATGGGTATCTGGAACCATGCTCCCTCTTCCGGAGGACAAGCCCTTAATATGGAATCCAGACTAAAGCCATAGCGATAGCAGCTTAAAACTAAGGCACGTCGTCCAGCCAATTCGGCCGATTCCGTTTGGAACAAATAGCTGTCTGTCGCAAACACGACCCTGGGAAATGATCCAGTTCTACCGCACCAGAAGCGACCCACCCCGTATTCGCGTGGTGTTCCTTCAAAAACGCCCCCTTGGGACTCAAGACGTCGAACTTCTTTACCCCAACCGTTGCGGGGTGTGTGAGAAACCGCAGACTTGAGAGCCCGAGTATCTAATGCAATCTTCTCGGGTAACAAGTGTGTGTACATCGTGACAAGTCCTTGGGGTCTGCAACAGTATGTCCGACCAATTGACCGACCGCAGCATAGTCACAGTCGGAACTTTCGGAGTAAATCCAGGAGGGACGCCTATAAACTGTTCATAGGTGTCAAAACGGGCAAGGAACCAGAGAATGATTCAGTGCATTCGAAGAGTGGACGCGGTAACGACGTATAAATTTCGCGCTTCCAAGTAACACCGGACCGCGATGTGTGTCGCATACCGAGTTCTATGACGATGCTCAGAACCTTTGTCCACTAGCTTGCAGTTGCTCGACCCTAAGCGTTGATCCGATCTGTGTACAGAGAATCCACTTCTTATCTCCGTTGGCCATTAAAGCGTTTGTGTCCAGATCGGACTTGGTGTGTATGTAAGGCCTGATACCGCACAATAGGAAATATATCGGCTAAATTAAATTGGCTCGGGATAGCCGATCTCGAATACGTCCATTACTGAAGCAATTGGTTACGCGCGAGCCCCCGATATTGACTTTGATAGTATGTCCAAACGAGTACAAACTCGTTGCACTTAAGTTCGACTTGCTATGAAACATAGCCGTAGGAGGATTTAACCGAGCCACAGGCGGCTCCCTCTATCTTAGCGGATCGAAGTAATATTCTGTTGTCATGGCTTTAATTGGGAAATGGCTGCCGAAATTTGGCGAAAGATAACAAGTTAATAAGGACAATTCCTACTTACCAAGGGTACTGTTTCGCAGCGGCCGGTACCCCTTCGAGACTCTGTTGATTTTCCGTGTACACAGGCAAAATGCATTGTATATCCCGGATTGCTTGCTGCTCATTAGGACTTTACGACATTAAAAGCAGACCAATTTGACCCTGCTAACCATTAATCAAGGTAAGCTGCTCTTTCACGGAGAAAGCGCGTGTCTGACTGAGTATATCTAATAGAGTTAGCGTACAGTAGTGATTGGCATGCCATCGAGAGGCGACGTCCGTAGTCAACCTACACCGTTAGAGAACCCTTGTCCGTTGCGCTTCTTAATCTTTTGTCGAAGAGGAAGTACATGAAACAATCAGATTAGTCATTATGATACACATCGGTTGGGACACATAATCTTTGCGCTGCAATACCCTACAGTGGCTGAAAGAGTGGCGTTGCACGCGGACTAGGATTACAGCGTATGCCCAGGTTCTTCGTACGTTCCTATGGGGCTGTAACTTAGTATCAGACAAGCTTGCAGACCCGCGCCCGGGCACCGTGCTATCTGAGTGCATGCCGTCGGCGTAAATCGTGCAGTGATTCTCCTCCGCCAACGGCCCTGAACAGGGTTCGGTGCTACTACTGTGGCAGGGGGGCGGGGTGTATGTTACCACAGAAACTCCTCACGCGGCAGGGTTGACGGCCAGTATACGCTATGAAAGCCAACAATTGGAGTATGAATCCCTCACGAGGCTTAGCGATGCAGAAGCTCGCCTGTAGACTAGTCTTACTAAGTGAAGAAACGGCGGACGAAATCGAACGTGGGTTATGCTTCGATAGTCAACCATGAGTGCATTCAGTAGAAGGTCGGAGAATCCACTAGTGTGCGGAATTATGGGTTCCATCTAAGGCGAGAAGGGTCCGGGTTAAGTCCAGCTTCTACACTCAGCAGGCAAACATACGTGGCCAGGCTCCTTTTAATCCCCGGAACAACCCACTCCGGGGGGTGATCCCGAAAGATAGATTTATGTTGAACAGGCAGTAGCGATTAAGGCAGCGGGAGTGGACATATATAGCAGCAAATTGTCTCCCTCGGGCCTTAGCTCTAGCTCCGGATAACATAACATACCTGTGCATTTGGCAGCAATGATGATCTTGTGCTAGGTTGACACTGGTTGGCGGACAACGCCCAGTAATGGGACTAGCCTGTGGCAGTTTGAGTTTATGCGTGAGCACAGAAGCGCGCCCGTCTTAGGTTGCTTCACACGGCCGATGTCACGGCAAATTGGTTTCCAGGGAGAGATTGACGTGTCTTGAGTCTACGCTCCGCGTTAAATACACCCCCCCTGACCACGTTATTGTGCGTTTAGACCTATTCAGTTCAAGGCGTATGGGAAGACAGCCCGGTAACGTCGCGGTCGATGTCGAGATCCGCTGCGCCCGTTCATAGACGACAGCATGAGAATCGACGGTCTTGAACGTTAACAGATCTCAAAGTCGTTAGCATAAAGCTCCTAGACCAGTCCGTATTGCCGAATGTCCTTAGACTGATAGGCTATGGCTGCAGACTCACGCATCAGCCCGGCGGGGCTTCAGCGATCTAAAGCTCGCTCCGAAGAAGCTCGGGATACTCATGAAGGGAACTTGAAGAGTTATATCGAGCACGGAGAGACCACACATAGCCCTCTATAGATTTGTAAAATTAATGGGATTGTCATACATGCCAATGGTATGGGCTAGAGGCGCCTGTCAGTCAAGGAGATAATTCGTACTCCCTTACTTCAGGGTAGATCATGACAGTTCAGGTGAGGTCATCTAAGGAAGGTCGCTCGGCTGTAGGGGTCTCGTACTATTAGCCCACCTCAGCCCATCCGCCTTCACTCACATATTGTCCCCCTGGCCTAATGGAATGGAAGGTGATCACTCTGGTCGGGTACTACCACCATATAAACACTGTCGCTGTAATTGTGTTCACTAAATACGCAGTCGAACGTCCCCAGTCCACGTCCGGGTGATGCCGCGCTCCCAAGTGGAAGGTATCGATTTAGGAACCATCGATGCTAAAGACTGTATCCTCGTACGCAAGCTACCGGGAGACACCTCCGGGAGCAGTGTCGGTACGCTTGTATAACATCCTGACAAACGCGTTAGTTGAACATTAGGCGTGGTTCGCAAGGTCGGCACTCGCTGAGACAGTGTAAAGTTTGGCGGCTCGTTACCATGAGGCCTTTTCTTCTTGGGAGGTGTTAACCCAGGGCGTGTGCGTATACGCCATAGGACTTACTAAGTTGTGGACACCCGCCCGCCTTTTTAGTTTTAATAATGCCCGGCACCTTTGCTTATGCGATTGCAACATCGCTGCAATAAGCTCGCTGGACGTATCAGGCCGGAGAGATGCTATCGCGAAAGGATTCTTCCCTCGCAGCGCGTTCGCATTCTCATTTCGATAGAGCTCGATTAAATCACGGAACGCTATGGAACAAGTGTGCGGGACCGAGAGCAAAACGCACGTGTTAGCACCTTGACCTAAGAATTGGGGATAAGGATAGCCGAATGAATGCACTTAGATGCGTTTCGCCGCCTGCTACCACATGAGCTGAGACAATTAAGCGCAGAGATCATTGGTGCTGTCAGTGCAATACCTATGTGGGCCGCCTTACACTAATTAGACATCCGCAGCCGCCCATTTGCGGCACGAAGGGAAATCCGTTAAACACGGGCCGTCCGAAGTCCACAAGCACAGGTCCGTGACCCGTGATGGTTCTGTTTTAAGCCATCTTTTGGCGTTCTGTCGATGAAATGCTGAGGTTAAGTGCGCGAAGTTGCTTTCCGACGAGACTGCTCCCTGCCGGCGGGTACGCGTACAGACCCTGCGGTCCGCGGGCGTGATCTAGATTACAATCGACTTCCACGGCTATCATCCGCTCGTTTGCCATGGAGTCGTGACAACCAGTCTAATTGGGCTATATCCCCTGCGCGAGTACTCCGCGGCCATAGGTATGCGTTACAGCGTTCCGGAGCAAAGCGTGCACTAGTATCTTCATCCATGAGGTAGACGATAGGGGTGGGATCGACTCCGATGCTAATGTCTAAAGTCCCCACGCATCTATGTCCCATAACACATGACCTACAGACCTTCTGTTGTTAAGATGGTGTTTGTCCGATGAATCGTAAAGACTAGCTGACTGTACGCAAAACTAGGTAGTTTGCTATCTGACCATGGGGTTTGTCTCTGTCGCTTTCGAGGGAATAATTAAAATCCGGGATGCGGGTTTCAGGCCCACGTAAGGCATCCGACTATCTACCAGCATACACGAAATTCTAATGAGTTCAGATGCCGTCTAAACAGCTGATAGTGACTGCCATCCTAGAGGACTCGCTCTCTTCTTACCCATGAGGTACTGCGTCGGAGTTTACTGACCACCCCCGATCCAGCTAGAGCGATGAAAATTAAGTTTTACGGACCATAGATGGGGTGTATACATTTACAGCAAACAATCGCCCTTGCTCCTAGAGTTACATACACGCCTCTACGACCTGCCAGCCAGATCTCGTTATCGCCCAAGGCAAAACTTACCGCAACGCGAGGCGCCTTTGGGACGGCTGCCTCATATAGCCGCCATACACATGACTACCCAGCGACGTTTGTAGAAGCAATGGGCGAAGAAGGACGATTCGAACACTATCAGGGGTGCTTCAGTTTACCTGGAAACGACTTTCTCTGCGATCCTATTCACGTCCTAAAGCATCTCCGCTAACTCGACGTTGAGATGAGCCATTGGGCTGGAACAACAGTCAGCCCCTAATGAGGCTACCTCGACCAGTTTTGGTTGCAAAAATCCGCCCCCGGCTCTCCTTACAATTTGCGGTCGCTTAGAGACATCATTATTCACGGTCGCCAGGATACTATCCGTACGAGACCTATGCGTAGATTTAAGACCCGGCATTCGTTTTTCCGGTGTATAATGATTCAGTTATTACCATCCACATCTAACATCAAGAAAACCAGCAGGCGTGATCATGCTTTAGGTGGGTCCAGAGGATGACGACAGGCTCTTGCTTATATCCGTTCACTACTGAGGTCCCGGGGACCCACATAAGGAGCATTGGGCAAAATACGATTGCAGAAGGCCGCAGCTGTGCTACCAATTCTTGCCTTCCGTGTTTCCCTATCACTAAGACACCGCAAAGTCCATCAGGTCGAGTCATCCCCAGCCGGCAAGCAGATTCAGGTAACTACACAACCTCACTGAGCAGCGACGGCTTATAAAAGTGCGTTTGTTAACTTAGGTCTTTAGCTATAACACGTGGCTGATCACACTCATTCATGTATCATCGGCGCTAATGCGGCAAGTGGGAAGACATCTAACCGAGGGTAAGAGTTCTATCTTAGATCCGGTATCGTCAATACTGACGCGAAGTTGCGGACCATTGGAGTGCGCGCCCTCTGGCTGTTTGGGGTATTTCATCTCTGAACATTTAAACATGTAAGAGGTTGAACGATCATGACTCCAACCACCTTCGCCCAATTCGAACAAGTTGACGGCTGTGTGAGACCCGCTCATAATACCAATAAAGAAGGTCACAAAGCTTAGTGCACGTTTGATGTGAGCCCAGCCCGCTAGAGGCCTGCTAAAACCTGCAGCTGACAGGGGCGCCAAGACGCGAATCTGTTGTATTACAAATCAAAGAAACCGACACATTTTAGACTACGAGCCAATTACGATATCGGGCCCCCTTCCCGCCGAAGAGTTTGTCAGTCACATAATGATCGTATGTCACCGATACCCCTGGAGGGTCCAAATATAAAGAACAGTCATTTGTAATCTGGGAAGTCACAACATTTATGACAGGAGATAAGGTTATACAGCCTTGTAAGACTCGGATGATAATATTCGCTCTATTGACTGGCAAGTATTGCACTATTTGCGAATTAAGAAACACCCGCGTCCCAGCTCGACATTCCCGAGTGTTCATTCCTGGTCCCATCTTGACCGGGTATGGACTGGGTCCCTCGATGAGCACCTGTTCGCTATCATGTGGGCCGATACATCACACACCCTGATCAGGGGAGTGCCGAATTTGCACCGTCCCTGTGGCATGAAGTCTGGTGCACCGGTTACAGGGATAGCCATTGAATTCAGGGCCTCAATGTAACCAGTAAGAGCAGTGGGAAAATGCTGATGAGTTCGGATGTGGTTGTAGTCGACAGAGTACCGCGCATACTGCTTCTTGAAACGTCCGCGAGGGGATATTCGGCTTGTCGGATTATGGAATGGGATCTCATAAATCTTGAACAACGAAACACTACATGCGTCCCGACCGTGCCAAGTCATCTATTTAGAGTGCGCTTAATATATCGTAAGTAAGTCTGCAACTGTTCCGGCCGTACTTCTTTGTGGTTCCTCACAAGTATGAACCTTGTGCTCTATTCCACCGGAAGCTGGTGACTGCAATCAGAAATCGACCTGTTCTCGTTGACTGCACCGGCTGACGCTTTCATACTCTTATACGGACGAATGAATTTCTAGTTAAAGCCGCGACTTTTTAGGAACAGAGGCACCGGTTGTATCTTCGCCCGGAAATATTGGCAGCTTTTGTTGCGTAGTTATGGCCATACTAATACCGCCTCATTAGTCTATATTGTTTGGGCACATATATCATCACGCGTACCCGCCCAGTACTAACCATCAATGGCCTCTACGAGACAGTAACATTTTAAGACCCTTAGGCGACTCAAGAACTTCTCAGCAGGGTTCTCGCGAGATCATAATCTATTGCGGTTTCGTTAGCCATAGCAGCATCTTGTATTGTTATCATGTCAGGTATGCGCTCTTGTGAGTCTGACGAGTGGTCTTGTTAGTCGTTTCCACCGCTCGATGCGAGTGAGTGCAGACCGCTTCATGTTCTTCGGTTGCTCGGAATGGAATGGGGCACGCAGGCGACAGCCTACCGTCCTGCCTGGCGAGGGAAGATTTCAAAGTCGCTACCCGATCTGGGTTGTTTCTTAGTCGGCATATTGGAGGCGACTCATAGAACGTTACTTCAAACATGGGATTTCATAGTTGTTTTAGAGCCGCAAGTCTTACCACACGATTGCATAACTTGATCGTATTGCGAAGTTTGAGTCCGGGAAAAACAAACCTCTAATGATAACACATGTCTGCCGGACCGCCTTGCAGTTATCACCGATCCGGTTCATAGGGTAGCCAGCTTCGTATGACCTTAGCCGATTACTGTAGAGGCAATTGCAAAGTCAAAGCGAAATTCAGGCGTACCTCAGACATAAACGGGAACCTCGTCAGCAAGATCGGTAGACCTAGGCTACTCACGCAACGCGGTATATGCCCGGTTACTACGCGACCACGTGATGTAACCTGCTGTGTTTTACCTGGATTGCCATCGCTGGCAGATAAGTATACTAGTGATCGTGTATTCAGCATTAGGTTATTTAGAGAGAACCATCCACGTCAGGTTATTGTTGTTAACATCGTGTCGGGCTCCATCAGAGATATCCGATCTACCCTGTCAAACAACGCGAACACGAGACAACTTTTTGCGGCGCCATTTGGCCGCCAGCCGCAGGCCCCCAACGTGGTCTTACCATGAAGGGGAAGCACTTGGACGTGAAAACTGAGGTCGATTTAAGTTTGACATACAGGACTCTACGATGACCGTCGGGTGACCAATAAGGATCTACATCTCTATTCTTCGTAAGCACTGATGGTAGTATTCCAGTAATGGGAAGCTCGCAGCCACTTTGATGCTCGTTTGATAAACCCATATCGACCAAGAGCCGGCGGAGTGGCGGTTTGCTTATCAAATTCATACAGCCTGAATTTGGTTATCAGATGCCTAGCCCCTGAAACTGCAGCTCAAGCCACTGACTACAGAACTGCCCGTTTCGCCGACATCAACCCAATCGAAAGCACGATGAATCTATCGGTAAACTCATCTGTGGATCCAAACAGCATCGTTGGCCAGTACGATTTTTGCATCCCCTAGGACAGGCGGGTCCCTAGTCCGCTTGGGGCCACAGCTTGAAGGATTAGAACAAGTCGTGAGGATAGTGTTCTGTACTTTACTATAAGTATTTCGAAACTATCCATCCGTTGAGTTGACTCACGTTCGCCATGGGTTGAAGATGGACCTTCAATGGTCCAGTGTGCGCAAACAACCAGTAAACGTATTATCGTATCGAGGCAAGCGACTCATCACGAGCGCCTCGTTGGGATCGCAGAAGGGACGTAGCTGGTCACCCCAGCTATTAGGCCTGCATTGACTGCCCGCGTCATAATTCGTGCGACAGTCTATCCCGGTACTCAGCTCTACGTTATGTCTACTAGATACTCGGCTCTTGAACACCTTCCGGGCAGGACCGGAATCCCTGTTCCAGTGCACGATAAGAAGAGTTTTCGCTTCACTGCAATAAGCCGTCGATTACACAGTGAATGTAAAAAGAATGCTGGCCATGAAAGCATTGTACAACCATGCCCAGGAGGGTCTCGGACTCTCTTTCGGACAACCGCACTGGCCTTTAGAGCTGGAGCGCGGGTAAATTTCGAGGGGGTCGACTTTTTCGGGTGATTCCATATAGGCGATGTGAGACACGGAACATAATCTGTCACGATGGATGTGCCCCATGACGACCGTTGACGTACGACAACTCGAATTCAAGGAGAGTAACGAAGCGTCCGATATAAAGTCCCAACGTCTTCCGAGATCAGACCCAACTAGAGGATAATATTGTGCCAATAAAGACAGGCAAGCACTGTGGGGTCGTCAGTTTTGAGCCTAGCGTATCGGCAGAAGCTCGCAAATAAAGTCACTGACGCACATCGGGTAACGTGGTGTCCCACTGGATTTAGCATTGCAAACGGCTCAGAGCGCGGGATATCGGTGTTCTCGACTCCGAATGTATTGAGTGCGCCGAGTCGCCTCGTTATTCCGGCTTGAGTCGCTCTCTTCTGGGATATGAGAGAATGCTTTCAGCCTCTGACATCCGCCGCGCATGAGAGAGAGATGGAGATAATAGGGTGTTGGCATTCGGGAAGGGCGCTCAATGCCTACCTCGTTCCCCTCATGGTTCCCGCCTTAACTTGAGGAAAGATGGCCAGTGTACTCGGACCCCCATGGAAGATTGGTTTCCATAGATTCCAGCAGACCTAAACGCTATCTGTTCTAGCACGTAGGTCGGAAAAATAACGGCCGTAATTGGTTTTTTTCCCAATATTACAGCCCTTCCAGAATTACATATCGTCACCAACTAGGAATACAAAATCGAGCCAGATTCCCAAGCGCTCCCATATCTTTATGGTGCATTGATATAGCCAAACCCTGGTAGAGAAAGGGTGGGCGTACATCGTCAACTCTTCTGAGTAAAGTCTCAATTGAAGTGTCTTACAAAACGATCCGATATCGACTAGCTGTCTCTGTTCCTTCGGTGCCCAATAGACATTGACAAGCTGTGAAATGTTGGTTGCACTAACTTTGGGAAGCTGCTACAAATGGCATAACGATTACGACCGACGGGCTCTATTCCCTTTTGCCCCATCCTACTCTGTTATCTCGCAAATCCCAGATGTGCGACCTCCTAAACAGACAGAGTGGTGTTCCCGCGATCTGCTAGAAGCAGAGTGGTCTGGGTACGACGTACCTTCCTCGCGGAAAGTTAACGGGAGGGTTACCCTCCTGATTAAGCTCCGCGCCCTCCATCACGACTCCGATGGCCCGTTCAAACGACCCACTCGATATAACAGGACTAAGCCACCGCGCAGGGACCGCTTGACCTATCGCCAGCCCGTTGCTGGGGGAGCCTTGCTTTGCAAAATTAAGCCCCGAACCGGACATTTGCGGTCATTGCAAGGGCAGATCTACTCGTAAAGTTTCCCAGTATCGAATAGCTACGAGTAAACGGAAGCATAAACGCATCAGTTATTCCGGGAAGCTCTCTTTAACGTTGCTATCTCGGTATTAAACTCATTTTTGCCTCCGTCACTTGACCCCACCGGAGACAAAAGGAAGCGCGCTCTAGGCGAGGTATCTACTCGTAACCGCATCCACCCGAGCGTGGGTATTTGGCCTTGGTAAGGAATCTATCGATCATCTGACACGCTACTCCGGCTCTAAATAGCTTCGTTACGGGGACTATTCACAAATCACTGGAACCCATCTTTGTAAAATTGGGGGGCTGGGGCCATACTCAGTAACTAGGCGGTTTCGTTATCCACAGTAAGCTAGCTTGCCCCTTCAGTACAAGATTCAGCACTCTATGTCTCATTGCGGGTGCGGTCCTGAATGACTGTATTTCTCCAAAAGTCCTCTGAAGCGTCATCATCGTCAAGCTCCTTATCCTCTCTAATTGTCAATATTCAGATGTTGCGTCCATCGGAGCTCGGTATGGCGTGATAATACCAGAAACGTGTTAAATGAATGCTGACGGAAGCCGTTCGACCATTCCCCGAGAGTGCATGGTCGTGTGGCGACAGATCCTTCATTTACGCTACACTTTTGGCGGTTAGACCTCACCTTCCAGGTGTGTCGTGCGCATCATTCGGCGCAAATGACAGGTTTTGCCGACTTGACGCCCTATCCGTGGCACCCCCCTACCTTCGTGAGCGTTGGCCCTGCGGCACTTCCCCAAACCCTGTACATCGTGGGAGATCAGAGACACTCATAAGTACTAGCGTTGGAAGAACCGGTGTTGGCGGGTGTCAGCTCTCTCTGTATCACATACTCTGAAGTCCTACCAAGAGGGACGCTGCCTACGCTACGCCCAGGTAAAGGCATTGGACTGCTTGTTTTGTTCGGCGTCGCCCATTCACTACATCGTACCCAACGGTCTAAATTGTTGGACCAATTTGTTCCACGGATGGGCGAGCTGCATCACCTCACAGCGGAACCCCTTCATAATTCGCGACCTTCCCGCAAGGTGAGGTATAAGGAAAAAACGGCATCCCGTGCAGTCGCGGACCGCCACTGGACAGGTTCTGAGTACTAGATGGGTGTGGCCGAGAAGATCCGGACTAAAAGTCGCCTCAATCATCCGTTACCAGTTTCTAAGTGTATACGTGAGCGACACATTAGCTCTGGGTTTCACCACCAGTCGAATGCGTCAATTCAAAATTGGCGTCCTCGAACACGCTTTACGAGCGATGCTCATCGCGACACTCCAGTCACTGTTAAAGGTGTTCCGTTAAGGCAAGAGCAGCTCCACATATAACGTCCATGACATGTTGCAAGCCTGCACCATACGTCCTTTTGGAGCCGTAACCTTTTCCGGAAAGAGGATTCAGGTCAGCATTTTAGGTCTCTATTAGTGACATTGCGGATTCGCTCCGTTAACTCAAGGCCATCATTTTGGGCACTCCTCGGAGGGACCTAATTTTACTCCTACTTGCGCGATATCGATTGACAAAAGGAATTGCGTCGTATTTTCCATTGATATAAAGTGTACTTACGGCCCTGACATATCCTCACGGACACGCCAACACCACCCCGCCGTTCACGTGCCCCCCCTCGGGCTACCAACTGCACAAGGGCACCACAGCTTGACATCCATCAGCATGTTTTTTCGACTATTCGGCCGGCACCAAGTTGACACCGCCGACTGACGCGTGGTCAGCCGATCAGAGGCACCAAAACGGGGTCGCATGCCTTAGACGAATAAGGGTGCCATCGATGTTGGGTATTATTACCGAAACATTCGGATTAATAGTTGAAATAAACCTCCTATTCCAGAGTACTTACCCTAGACCTCAAATAAGACCTGCGAGTGGATGGTCTTAACAATCGGGTGGTCGTGGTCCCGGTTTGGGATAGCGAAGGATAGGGCAAGAGGACGTCCAAGTCCAGTAAACTCCAAACAGCACGCTCACTCTAACAGGGCGGTGATAATGGGGTAGTTAGACGAGCACTCATCGAGCAGTACTTGCAACTGTCTTTCTCCAAGCGACGCTTGTCCCAATGGCATCCGTAGACGACGATGTGTCGGTCCGCCGTCAGGGGAATTATTCGTATGATGCCTCGAGTCGGTCTCGGGAACTTTTCTCGGTTTCCGGTTCCTAGGGTTGCATCCCTAGGTCCAATAATCATCTGTCGTGAAGGGGCGAGTCCTTCGGGGAGATGCTAATTTCTATTGGCCCCAACCAATTTTATGAAGTGTCGGGCGGCGATGTAGTAAAATTTATTTCTATACCATGAAGAGTGCTCAAAGACTGATCCAGGTTCTGTCAAGCTTTTTCTACTATCTATGAGACCCTAGCCCACTATGCACTGGATACGATAACGATGCTAAGGACTACGATGATGCGTGCGGGTATTTACGCTTTGTTGGTTACCATAACACCCACAACGGATCTCTTATGGTTCTTTGATACTTTAAGATCCTTACAATATATCAGACATGTCTACAAGCCCATTCGGTGAATTCTTTTCTCTCTGAAGAGGGTTTTGGCGTTCAACCGGGTATGCTGAAAAGCGACTAAAGTTAGCGCGAGAAACATTATAACACAAGCTCGCTGTCTTAGCAGGTCGGGCTATGCCCAGGAGGGGAACGATGATGGACACGTGTACTTGTGCGACCGGTCATGGACATATCTCTCCGTTGGAGCGTCCGTTCCCAAATGGAGAGAGACTGTGACAGTTATCTACAACTGCCGGTAGCCGTGCCCACTCCTACGGTACCGCTAGTCACAGGGATAGCAGGAAGTTAGTCCCAGTTAGCCATCACGCGGAAGTTATTGACCGTCTGAGTTATTGTTCCCATTATGAGCCTAGCTGAGATGAGTCTCAGCGCGGCTCCGCCTGTTGATTAAAATGTTTCCAGATTAGGTACTTCCATGAACTGATTTGCTCATACATTGACGGCGGGCGAGATGACTACGCTTGCCGACTACGTGGGCTCGGCTCACAAGCTGCGCGGAGTGATCGAAATCAAGTCAGTTGCACATAGCCTCACCCAGCACCCTTGACCGGAGCAAAAGTGCTGAATGACTGCCCGCGCAACAGCTCATGTCTAACTATAGGTCCAAGGAGACAACTTGGAGAACGTTCCTGCGCAATGCTCCCAAGGTAGCCATGTGCCAGGTAAACGCCTGCTAATCTAGTTAAGGTTACACACTAGAGGGGTCCCATTATTGCTCACGTGGGCCACGTGCTACACTTCGCCCATAGCGTACGGTCTTTCACTAGTTCCGGGTACCCACATTACGTACGTTCGTTCACTACTCGCTCAGTAGCTAAGATCGGGCTCTGGGGAGTTCCAATAGAGCCAGGTCCGAGCCATCAATTGTCTGACATATTTTAACTCTAGAACTAAAGCAGCCCAGGTGGGAAGGCCACAAAGGAGCAGCCGGAGACTATCAGATAAATACATACGCACCACTAGTCGTCATAAATAAAGGAGTTGTCCCCATGCTACTTAGGATTCAACGGCTGGTAACGGGACGACAAATAGGATTACGGTTCTGTCTTAGTAAGGCTTATTCTATGGAATGGGGACGTTGGGCCTTCAAGAACGTAAGGGAATGTCAAGTCCGGCTTGGTTTTTTCCTGATAGGCGTGATACGCGAGCTTTTGAGTGTAATAGCGGGAGTGTCTGTTGTTAGATTACTTTTTCCGTAGTATCTCACTCAAACTAAATTAACACCAGTAGGTATTATACGCGGAATCTTCCGCTTTTGACGTAGAGCATCCCGTGTCCAAACCGAATTGTCCTTTTTGGATCGCATGACATAAGGTTAAGAATTTACCACCACTCGTAGGGAAAGACCAAAGCGGGACAGACAACTGCCAGCGGGGCATAGCCTACTTCCTGTTATATCAAGCTCCAGCTGACTCAGAACCAGAGTCAGTAACGCCTATCTCTGACCTTTGGGTACTCCCACGCGGTATCATTGGCGACCAGCTTGTGGAGGATCCATTTAGCCACTCAACTTGTTTCTAGTAGAATTGAATAGACACTGGAGAGATGGCCAGCGACTGATCTTGTCATACACTTGTAGGTACTGTACCTAAGGTGGTTCAATCCTGGCTACGGGTAACAGTTGGTGAGGTGGGCCCTTCCTTGCGTTTGATGGGGGCAGCCTCGTTGGGACCGACTACCTAACCAGGTATGGTTTCCTCGCAAAGCATGGGCCGCCAGTATCAACTTGAATTCCCGGATTACGTAGCAGATTACTCCTGTAGTTCTTACACGCCCTCCTCTAGAGAGGAGCCGCCACATAGGGTACGCTCGTCCTGGGGATATTCACTATACGACTGTGTACTCCCTGGCACTGCGCAATAACCGGAAATAGGAACATGATAGCAAATCACAGGCATTGACCCCAGTGAACAATACCAACCTCAGAAAATGGGGGAACACCCTGCACCTCCGTGCTGCCTATAATACCTCATATCGTCGGCTCTCCATATGAGGGATAAAGATTCTTGTGCTTCGAATTTCAGACAGTCGACCAGTAGAGCAGAATAATAATCGTCGACCTGGTCAGTAAGGGGGCCGGCTAACGTAGACGTTCCCTCACGACCGCTCAACGTGTCTAGACAAGCACACAGCATATTCCGTCCGGATCCACCAGTGTATATTGGTAAGTTGCTCCCAACTGGTCAGGATGATCCTCGAAATTATTTTGGATAAATAGATACAATGCCTATCCACCCAGGTAACACCACTGGTACGCTATTTAACGCCTTCTCCCGGGTCGCTTAACTAAGTATGCTACACCCACATGCTTCAAATATGGTCGTTTCACCCTGTCGGTAGACTCGTCAGACCTTGTCTCATACCCAGTGATTTCAACCGACCAGTGGTGATATAGTAGACCCTGGCGGTAACGATGTATCCTTATTGACTCACCTCAACCCCCTGTTCACACACATTACGCCCCGTCCGGGGCGAGTAGTGCTGCCAGGATTTTGGGGATACAAAAGGTCTCTTCCTTAGCGGTGTAGGGGCGGATTTACCTGTTTCTCAGGTTAGAGTCACATAAGCTCTGAGATAGATATGAGGGCGTCATAGGTTCGCACCGGACATACCTCGCATGTCCCCCTGGCGTAGCCACAAGGTGACTAGAGCCCACCCTGTCCGCGACCTTATGGCCCACATCTCGCTACTCACACCATTGATGTAATAGGGGAGTTATCCTTCGTTCAAGTCCGTTACCAGGTTCATCAAACAAGCTTTACGGATTGAAGCATCCCGGTAAAGACAGTAGCATGACTCCAAGGGCATTTTATAGCCTTAAAGGGCGTCCATGCGGGCCGGCAAGCCACTAAACCTTCATCTCGGACTGTTGGTCCTCTTTGCAAATTCATGAATGCTTTATGCTGGGAGACTAAGAACTTTTGAGGTTTCTATAGTTCAGCGGTGCGACGAAGTGGTCAGGCGCTGTAAATGAATGGAATACTCCTAGCGGGTTACCCCAGGCTTGAGGTTTTCCTAATAAACCCACAGCGTGGATCTCACCCAAGGCGCTAAGCCATAAATCAAGTCCCTAAATGTCCTTTTTAGAGCAAATGATCAGATCTCTGCGCGAAATTTGATCAATGTAGGACCGCAAAACCGCGAAGTCCCGCTGCAATCAAAAGGCGTTATACCGCCACCATTCCCGTGTGCAAATATATAGGCGACACCGCTGCAAAGCTCGGCTCATGCGATCATAACCCCACGCATAGCTTCCTCAATGTTATTTGCACTTCCCCCATCACACTGATATGCCCGGATGAACACCATTCGGGGTTTAATAGCCAGAAGATCCGCCTGCCTAAGATAGATTGTGGTTTCACCGAAGTAATGCCAAGCCAGTAGGTGACAAGACTGTTATCCATTCACGGGTGTAATATTTGGCGGTTCTCCTACAGGGTCGTTCCATGTGCAATGGGCCCTCTTACGACCCCGAGCAGCCTGAAGTCTGTCGAATTAATCTTATTCCTCAGCCCGCGGTCAGGAGGGCCGTAGGTCATACAATCAAGTGAACTCTGGCAGCGTGACGGCAGAAATGCGTAAGAACAGGGCTGTAACGATCCATGCCGGGTCAAGAGAAGGCAAACGGGGCTCTAACGTCCGATCTCGACGAAAATCGGAGGAACCGTCGCTAAATCGCTGTGCGCATTATTTACTCGGCTCTCTCTTGCCCATAAGTTTCTAGGTACGTACGCACCAATAGACAGGGGTATGTACTTTCGGGTAAGCACTGATCGTGGTGTTGTCAATCGGCTTCACTAGTGCTAGTGCTGAGAGTTCACTGTCCTTCTTCCGTGCTAGTTAATGAACCGCTTTCTATCCGGAGCGGTCTTCTTTCGCTCACTTGTAACATGCGCTAGTGGCACTACCGACAAGCAAAGCTAAGGTGCCTCCTCATCGACCGGAGGTCCCTCCGAGTTTAGACGAGCTTTGTTCACTCAAAACGAACACGCTGCGCATAGAGCAGGAATCAGTAAAGGGAACAACCTAACTGCAAACACGTGGCGGCTTGTCGTGTCTGACTACCGGGCAGTTCGGGTCCTAGGCGGTTAGTGAGCGGAACGCGTCGCCGGGCGTATCCGTAAGGATTGAAATAATTCTCTAAACGCCCCGCGTCGAATCTATGTCCCTTAGGCTGTGCCCGTCATTTCCGAAGCGCCCACAGGTAAGAAAAGATGGGTTTTGCAAGGCAAGGTTGCCGATTGGCGTTCGCAGCTGTTTAACAGCACATGCCGCGTGCTATACGGCAAGGAGAGCCTCTACTCATGACCGTCATCACACGCCATATGCCGTGAACCCCCCCGAGGAGTAAAGCGATGTTCTGCTGTACTTACTTCACAATTGTTAGCCGTGGAATTCGCATTCATTCCAACCGTTTCAATGATTCGAGCAGGCGAGGCTCCTGGGTGTTTCGTAGCAGGGCCCAACCACGAACATCTCCTTAAGCATCCACCCACGTGTAGTATGCACACCATAGATGGCATATGATTGTTCGAATGCTACCGTGATGCGCCTGTCTGACCAAATACCCTGAAGTTGCGGGCGCTTGTCCAAAATATGTAGGCGGGACACAGGGCCAACGTATTCCCTACGTCCGTGTACCTAGCTCAGGGCAAGTTTCTTCAGATTCCATTGGGACCCTGTAATAAGCAGCTTTTAAATTACGCTCCCTTCAACGAGACGGAAGCGATTCCGAAGCACCGAACCCTCAGAAATGGACATAGCTGGTGTTGTGGTGAAGCCTGAAATCCGACTCGGTACTATTTGTCATGGGGCTCCGGATATTTGTTGATCTTCGCTGCATTTGCGTCAAACTACGACACAAGTAGGATGGGCGTACCGCGAATTCATGACATGCGCCCCGACTATCATGAGCCAGAATGTAGAATCCAGGCAGTACCATTGGGAATGATTCCGTTGATTTGCAGACGGCGCATTCACTCTAAAGACACATATTGCAAGATTAACCTTCACTTTAACTCATGTCTCATACGGGTTGTACCAGCTGCTAACAACTTGACGTGGATGGCCGGGAAAAGACAGTAGTGGGTAAGAGGCATCTATCAGCGATACCACTTTGAATATGAATTATCCTATTAGAACCGTTCGCGTCGGCTTCTTAAAGTTAAAGGTCAAGAAGCGCCGGCCATCGTTAGGGCACATAGTGGCTATGAGTTGCGAACGTCATAAAACTCGTATTTAGCGAGGTCTCGGGACAGGATAGGGTTGCTGCGTAATTGTACGCGGCAGACAGTACAAACGTGCGCGCGGCGACTCCTATCTCTCCCGCTTAAGCTTTATATCAGCCTGCGCCGGGTGTGCGCGCGAAGCGAGTCTGAGTCCCGGTCGCTAGTGATAAGAAGGCACGTGCTCCCGAATTGCCCCCCTCTAAGGTGTGGTCCTGACGAGACTTTGGATCACGCCTCTGCACAACCAGGGGTTAGCAAGAAAAGCCCAACCTCCTTGACGGCCGTTCGCCCAATTGTAATGTCCGATATTAGGCGAGCTCAAAGTTATCGGGTGCTAAAGCTTCCACTTATCTTTAGAGGGCGCACAGTTGAGGTACGGGCCCGAGAATCGGTTCTGCCACGTAGACTCTTATGTGGTGTCGTATGTGGCGTAGTTCAACCGCGTCACGACGAATCGTCATAAAGGGTAAACTATCCCTAAGGGTTTTGGAATCTTGCGCAATAGTCGCCTTTGAACGGAAGAAGCCTTACCCCTCTGCGTTCACAGGGTAGCACAAGCTGCGACGAGAGTTACTGGTTGTTTGAGGGGTGCCCTAGTAGGACCTCCGCCGTATTATGTACTATCATCCGAGTGGGCCACCGCGCCCGCCTTAAACACATGCTACCAGTCTGTGCGAGTTGCAGGTGGATCGGCAAGGGGGGGTCCGCTACGCATGTAACCATAGGGGAGGGGTAGCAAAGGTGCGAGGACCACATGCCGGCGTAAAAACGAACTCTCACATGTCAGGCTTTGCATTCTGCGCCCCATAATCATCTAGGCTTTGCCCCACCGTAGCGAAACAGTTAATGCTTTGTCGCTCGTGGCTTAACTTCCTACGCGTTCTAGTTGCTACCCGAAGCGGCGTGTGGAGTCTGCGTTTTTAAGACCGGTGTAGTTCGCATGCAGACGTGAGACCCGAGTTGTGCTTGTGCCTTGTGGTACAACTCCACATATAGTCGCAGTGCGCACGCAAGGCGCACTTCGTCGCTGGCCGGGTCGGGTCGTACGTGCGTTACGAAGCAAAGAGTTGTTTATTAGAACGCTGTGATCCGCACGTAAGACCCGTTACTAGCTGCTCCTCTGTTCTTGCAAGGAGTGGTCAGCACGTATACCAGAACAATATCCTGTTAGAACTGTTAGACATACGACACTTCTCCACCTGGGATACGTAGGAAGGTGCCCCCTCACAACTGATGTCTTCCGCATCGCAAGACAACGTTGCAAAATATTACCCAGCGCCGCGCGTAGTGTGCACGTGCTGGTCCCTCGCAGTACCGACGGTAGATTTAACTCCTAAGTCGTTAAAAAAATTGTGATTCTACGAGGAGAGGCCTACGGGTTCTTTCACCAATTCGATAACTTTCCGACCGTCATATTCCCAATGAATGGAATTGAACTGGACAACATATTACTGACATAGAATCATGCGAGTGATCAAGAGTTCAGGAGTAACAGGTGATAACCTCGGTCGTGGGCCCGCGATTAAACAGACCTTAATGCACTGGATCAACGTTATAACTTCTCTGTAATTGGACATATCTTGTATCCTACCCAGACACTGAGGCACGCGGCTGGCAAGCCCCCAGGACAAGTTCATGCTGCGATGGGCTTTATTCGGACTGCCGGGCCTGACCAAGGCCGATCTATGAGTAGGGCGCGGTAAGAGCGAGCCCCGTTGTCCCAGCCGTGCTGAGGGCCATCTGCCTGGTAAGATACACAAGAAATACGCCTAAATGTTCGAAGAAGGCCTTAGATGATGAAACGTTCTAAACATGCGCGCTAACAGGCCACACTGTATGACATTGCCAGTCTCAATGGGGGATACACTTGAATTAGCCAATGTCTTGCCTCGCCTGACACCACTCGACTTCGCTGCACGGAGCAGCGCTTTTCCTTCAGTAAGCCTATAAGGGGATCTCTCTAGTCACGAACTGCGGTTTAACCCGAGAAGACGTTCCTAGTGAGAGCGCGAGCTCCGAGTACGTTCGGCTAGACTCCGTGAATGGGAGACTTAGGAACTAAGCAGCGCGGGGTTTCGTTTATTGGTACTTGTGCTTGAGCGGACGGGAGCACTTCCTGAGGCACATGCCGGGCGGGGTCGCAGGTAGGCTTAGCAGAGACCAGTAGCTCGTCCGCCTTTCCTCCCGAGCGTGAAAGCGGTAGCCATACACGGGGCTAATAGGGAGCGCACCATGCCCACAGTAGGCCAGCCCGGGCCTCACTCCCCCCATTTTCAGGCTACCTGCAGAGCCATTCGGGTTCCGTGGCGTTTCAGAGAGACCTGACTATCGGTTTGTGTCAGCCGATAGTCTTGCGATGTAACACACGAAGGGATAAAAAAGCGGCCGCAGTGTAGTACCAGAGGTATTTAAACGTTAGACCGAAATTGAGTTTTCGAGCCTATCGAATAATTTCGCTAGGGCTAGGTGATCCATTGGTTGAATTTGCACGCTTGCAAATACAGGCAGTGTGTCATCCAGCTCGCCATAAATGTTCAGGCGACTGACAAGAATTCGAAACTCACACGCACTAGTATTAAGCTTGGGTCACCCTGAGGCACGGGCGATTGTTCCGGGATTGATATCGGACGCCGCTTTTTAAACGATGTACAATTATCATATTTAGCCCATAGGCTCGATCATTCAGCCTTATGCGAACCTCGAAGGCAGGCGGAGTTAGTCGCAGTCCTCAAGGTGCCTCGTAACAAATAATGGGCAGCGCCTGACAAGGGTTGATGTACACTCTCACAACACTCTTAATTCAAAGGAGCCCGCTTATGGATAAAACTAATCCCAGCATTATCTCTCTAGGCTTTTTTTGGGAAGCTTAATCTCACACCTTAATTCCTCGTTCGCGGCCCCGTTGACAAACCTCGACGCCCAGCCTTATAGGAACATTAGATACTCGAAATATGGCAGCGAGAAAGTCCGAAGTGGCTACAAAATGACAATTGTCTACATCGGGAGTATTGCCTCGGTCTTTGGTTGATTGGAACGGGGTTGCATAAAGTACGCGTACATATCGTTGCCGGATAGATAATCTCAGTATTATTCTATTTCATGTGTGTGTAACGGCTACTCCGAAGTCCTGTCAATCAAGACGGGGGCAAGCACAACAGTTCACTCACGGATAGCAGATTATTTACGGCTGAGTTCAATATCGGCAGGAGGAATTAATTTGAACGAAAATACACGCCCCCGGGCTACTGTTTAGCAAGACTATCATACGCAAATACTATGCCATTGCTCGGTGGAATTTCGTTTCCGGACCATGATAAACCGTGTTGTTATTCCAAAAGCGAAAATTTTGATTTAGATCGGACCCTAGCATCCAATGCAGGATCTAAAATAATAATGCGGATAAAATGATAAATTCCCTGCGATCGACGGACGCTAAGTATTGAAGAGCATATAAGAATTGAACGGGTGGCTCCTTCGGTTATGTGGCACTGTTTGCTTGCCTGGCAGAGTATATCAACAGTGATCAACGCGGGAAACTCGGCCGCGGTCCGATGCTGTCTGCTTGGTTACCTCCGGTTTACCATCTGGTTCTACGTCCACTTCGTGCATTTTTGTTGGGTAGGCGCACCTGATGAATTGAGCTGCCCCCGATTTCGCACGTCTGACATCCGAATTTTTTGTCTCAACTTGTCAATTCCGGATCGTCCTAGCTCAGAACCCACGGATCAGCTCGGATAATTTGTTTGGTTGTTTTTACACGTTTATCATACGAGCACAATGGATGGGGCTCATACCCCGGCCCTGCCGGCGTGTGACGAGTGGAGATATTCCTTCTCTAGCTGTTCCTTGTGTAGGAGCACGCTTGGTCCTAACCGTAGCCACTTCGCGATATTGAATGGTTATGTTGCAGCTACAACCAGAACTGGTTGAGGGAGCCCCGAGCCTCGATCGTCTTCACGTCCATACGCATTCGCCACCCTAGCTGGGCTTAGACGTTAAACTGCGACCGGGTAATTACCTAATTCAGTCAAGCGTCCCGTTCCACATTAATATTCCAGATTTGCTTAATGGCCCAGTTAAATCTATCATTACGTAATAGCTGTTACTCCCTAAAGCGCCAAACTTTTGACCCCTTGTTACTTACAAATAAACGGGTTGCGTCTTTCTTTCCACGGACCTCCATGCTCGAATATTGTCTCTTTCCGTATTGTACTGTACAACTCGGTGACAGTTCGTAACTACCTTCAATAGCAACCAACCCCTGTTACACCCGTCGGGCTACTAGTTTCTCTTTACAGCCAGCGTCTGCAGGTAGCTCAGCCCTCAGATTCAGACACAATATGAGGCTCAACTTTGCACTGAGTCCGTGGCCGGAGGGCTCTGGCTAACGGTTACGTTAGCATGAAGTACTGGCTTCATAGAGCCGGGCCTAGTCACACTGGTTGGACACTACCCGGATAGAACGCAAGTTATAAGATATAGGGCAGGTTCTGGGGTGTGCCTGGATATTTTTTGTCCCAGGTTCCTTGCGGCATTGCGTTCAAGGTCTCTCTTACCCAGTCGTCATATACAAGATAATACTATCGACAATCTTGACAACGTCTGTTGAGAGCTCGCGTCATAGGGACGGCAGCGCTAGGGAGGTATGCCCAACCGGGAATGTGGGGTTCTCCACACCGTATGTCCGATGGGCACAACTAGACCGTGTCATTATAAGAAGCTACAACCGAGATGCCGCACCTCTTTAATGTTGATCCTGTATTGTGAACTATCACTCAGCTAATTCGGGGCCATAGGATATAGGCTTCTAAGTCGACTTTTCCGATGAAAGATCACTATCCAGCGTGTCAAGGGTAAATGACATCAGGACGCTGACAATTTGGCTGAATCCTTGGCGACGCGGCAAGAATAAAGGCATAGCACGGGCGTTTGAGGGGACGCTGATTGGCTCGGGTCCAGGTCTGACCTCCACGGAGTCCGGATTCGAACTCGGTCAGTCACACGGGAGGCTTAGGAGCCTTCGAACGGACGATAATATCCCGTTACTCGCCACTGTGCCTGCCTATAATGGAAAAGACAACTTTTTGGAAGGAGCTCGCATTGTCCGCGGCCGAGCGATTTCATGTGGCTTTGTGAAAGAACTCGAGTTGGACATAATGTCTGTATATGTATCGCCGACGCGACATATCCTGTACGTGTTGTCGATGATATGAAATTGACCTACTTACATGATACCAAAAGGAGGCGGCCCCCGGAAGGTTGGCCCGAAACACGAGCTCCTCGCAAATGATGTCATGACGATGGCAGAAGCCGAGCTCACGTCTCATTCGGTCGCAAATCCTTGATTCGTGCCGTAAGGAACTTGGGAGGGTAATAGCAGGTGCCACGTTCTCCTATTGTCGGACGCAGTGCTTATGTAACTGATTCCCTGAAACGTAAGCTATTTCGTCCGGAGATAGAACATTATGTCCACAAGGCAAGATATGTTTCCTATGAGAAGAAAACGACGCTTAATGACTTGGTGTTCTTTCTCCAGGCAAGATACGCGAGCGCCTACGGAACAAATGACGTCGTCTACGACGTCCAGATCCCAGCTTTTCGTTCGCTGCGGCCCCCAACTTTGCCAGTAGTGCCGATTGTGCGTTGCGGCAGGGGTCCTTCATACTAGTGCTTCATGCATTTGCCAGGTACCATGGATCTGCACTACTATCAACCGGGGACCGCGCCATCGCTTATGGGGTAGATGATCGCGCCACATCGTTAAGCGCGGATTATCGGAAGCAATCGTCCCACGTATCCTAGGTATAAGATATAAGTTGCAACCGCCACTAATCCCTCACACTTTCCACGGTGGAATCAGATGTCAAGCACTACAAACTTGGTCCACAGATGGGCAAATATATGTGCTCATCTCATAAAAGGTGTGACCGCTCGTTCCGGAACCTCAACTTTTGCTCGTAGCGGGTATTCCTGACGCGATTCACCAATCGGGGCCAACGGCTGACTTAGACCCGGCAAATAACACAGTCCAGCGTAGCTTGCGCATTTACGGCTTTTTGAGCTGGCGTTCCCGCCAGATTTGCACAATAACATCGATGAACCTGTGCTGCGGCTAAATGATAACGGAATGGACAGTTCGCAGTGCTTCTGATTGAGTTCGTGACCAAAGTCATCCGTAGGCAGGGCACTCTATACCTCACGTATGTAGCCTGTGTATCCTTGCCCAAAGGCGCGCGCAGCTCGAGGAGGCGGGATTGACCGGGACACATGTATTCGCCTCCGAGCGAACGCAGTAAATATTCATACGCAACGAAAGAGCTTCTTACGGTATTAACAATTTCATCCGGGGGTTATCGAGGATCCGCGCCACGGGTCTGCGCGAGACTCACGTGGCGGCGGATGAACCCGGCAACAGTCGGTGCCCCTGCTCAGCAGAGCGTTATTGCGAAGTCCATGAAAACCTTATTCACTAACCCGGAACAGCCCCTTTAATACCAAGTGTGAGTAGAATATTCACGCATGGGCAGGGTGTGGCGAAGAGGCGGCCACACATCGACCGGAAATCTCTGTCCTGCGTTCCATACCCCGACGAATTTCATTTCCCCACGGACTAACTTTCAGGGGGAATAAGCGAGGTACCCCTGGCAGAAAAGGCGCAATGTCTGATGAAATTTCTCGTGATGCTCGTGTGGACGATGGCAAAGCTCATGGAATTAGCTAGCAGCAGTGAAGTAAAAGCCGCTTCGGCGGCGACGGAGTGTATCACATCGGGTCGGATGTGGTCGCGGAGTGACGAGATCGAGGATGTGAGAGATAAGGCCCGTAGATCGGCAGGTGTGTGCCCTACGGCTCACTCGTGGTCAGCCAACTGAACTCGTGACCCTCGTTATGGATCTTAAGCTCTAGTAGGACAGCCCAACTACCACGTCTTAGAAGCCAACGATAAGCCCATAGGGCAATGTTTTTAAAGGAGCCCCCGTTCGTTTCGGCCACAATTAAGAATTGAGTTGATCATGAGGACTATGTGATTTAAAAAGTACACGAAAGGCGCTCAACGGAGTGTACTAGGCATTAATCATCCGAGTACATGCTATAGCTTGTCCAACACTGTGCGATGCGGCGAGCGCGGGTCTGAAACGCACCCGATATTGGTTATGTGTTGGGGTGCCCATCGCGCTGTGTCCCCGGTGGGAAAGTGATGTGCCATCATACAAACGATCGTAAATCTGCTGATAAGGACAGACGGAAGGCTAAAATGGAAAGATTGAGAATTGGGCGACTTTCTTTATTCTCAGAAGCAGGAATAGTCATCCGTAGTGCCGTCAGTTAGTAACAAATAGTTGCACGCTGCGGGGAAATCCCCCCACTCCCGGAGTACCCAGCAAGTTAGGAGGGTGAATCCCGGTTGGGCTCAGCGGACACATGGTGCCGACCAGTATTTCCGCATTTTACGGGACCCATACAACGCGTAACGCTTGACACTGGAAACAATAATAGATGTGTCATGAACTTCTAAAGGTCAGTTCTGTCGTCGATCAGTGCTCTCCGCGATACCCGAATGCGATTCTAAGAGTGCAGCTTTCCCTAATTTGCTACGCGACGTATAAATTGGCCTAGATTGATGGGTGGCGTAATGAAAAGTTATGCTGTTGGTTCGTATCCTGTGTATTTCGGTTCTTCAATTCGCACAGTGATTAACGGCCCATGACTGATGGACGTGGGCGTGTAGTATGGGTATACCCCCCTCAATCACCCCGAGTGCACCTTCGTGCGAGAAGCACATCGCCTACATGATTGGGTACCCCCTAGCTAATGACACCTCCGGCCGGTGCGGCGGAGTCGTAGAATGGGCCAATGATTCATCCCCTTGTTTCGTCAGTTCAGGTCCTGTGATGCACCGTACCTGCCTTATCATTCTCGAAGCCTGTTTAAGTTTCGTTTGCGAATTCTGCGGCCTGCTCTGATCCGGGGAGACCTTCGAACATGTGGTACCGAGACTGAGGTGAGTAGTTCAACCATTTAACTGGAACAGCTAAATGTCGCTTTCGCCCCTTACTTCTTGTATCTTTCGTGGCGTTACCATGAGGAGGGCATTTCTGACTGTCGCTTGGATGGAGGAGTAGAATAACCAGTACCCTATTCTGGCCCTGTCAGCGGCACCGGAAACCGGGCCGCACGTGTGTTCGCAGTCATTTGTTGACGAAGCATGCGTCCAGTGAAACGTATCAGGCATAACTTGCAGGGTAGGAAAATAGGCACTCGTAGCCTAGGTGCAAGGCGTTTTATGGCGCTAGAACTTAGAAACGAAAGATCCGGAGCTGTCCGATAACTAGTTTAAAGAATCACCATCGGGGGATTGCCAAACGATACTACCATTCCTTACACCAGTGAGGGGGCGCTTAGTGGGCATGGAGTTGACGCGGGATGCGCGGGCCAACAGATTCCAAAAAGTGACGCTATTTAAAGAGGTGGGCTATGGAATCGGCATGCTTACAGCTGCTCTTCCTCCTGTAGTAAGTATATGCGACCGATGGAGGTCAAAAGGTCTTGATTCGTCGGTGGCCGATGTTATGCGGTGAGATACCTCCCAACGGCGTTGATAAAGGAGGAGGCTTACCATTACGCCCATGTTCGAGCCCCCAGCCAGACATCGGTACCAAGAAGGGTAGTTGGATACACCCCGTTGCCACCAACGAGTGTCTTGTGATTGGCCGATTTCACCAAGGGCAGATCGACCTGGCGTGGAATTCCCTTATGCAACAGAGTCGACAGTTTGGGGTGTAACAATTGTGCGTAGGCCCAGCCGTCGAGTGGTCCAGGGCTGGTACTATACAGCTAGCCGTACAGAATACTCGAACATTGATCACCATGTGACACATCCGAATAAAGGCTAGCTACTTCCGCACAAGCAGATATATTGCCCCGAGTGGATTCCCTGGGGTCTCTGAGGTATGGGGATAACATACTTTTTAGGACTACAGATAAAAGTCTTACATGGAAACCAGCTACGCGTGGTAAACGGATAACGCCACCGGATGTTAATTGGCCTCGCGAGAAGTTTCATATGCACTTAGGGGTCTTAAGCCGTAGCGCTCGGTTTATGCGGCATTGCGAAGTCTGACGAGGCCATTCGACAAGTCCAACAACTTATCACACTTGGTTTGTGCTGGGCTGTGAAGTCTGCAATTGCAGGTAACTTAGCACTCCGTGATCTACACCCAACCGGCCGTACCTCTTGGGTAAAGAGACTGACCCGGGTGTGATATCTGTGGTAGCCAGGTGTTCATTCAAATAAAAATTGTCCTAGCATTCCGACTCTAATTTTCAAACCGTTGCAAAATTCATCGTTCTAAAAGCAATAGCTTGAGAGGTCCTTTTTTACGGGTCACTGCATCAATATTCTTTCCTCTACCACTCAGTTGATCTTAGTCACGGGTATAAAATATCCCTACTGTACTGTTTGCCGGGCGCGACGGTATATTACCCGTGGGGCGGCGCCATCCGATAGACTCGTATATATCAATCACTTCCGCGGAAATTTTCAGCGTGAGCCAATCGATTGACACAGAGTCCGGCACCGGGGTGACGCATTGAGGTCCATGACACTCGAAACTTGGGCTACGACAGGCGCGGGACGGCCGGCTCGTTACTGAACTGTCAATGGGGATCGCGTGCTTACGGTGCGCGAAGGATTTATTTGAACGAAGGCATCTTCTTAATTGTCTTCATTAAAATGGCCTGGTATATAGTTCGCTAGGCGTTTCTACAGTACGGGTAACTTTCTCTCAAGCAGGAACCGCAAACGTCGATGCTGCAGTGGCATTACGGGGTGATCTTAACATCAAGGAATATCTCCGGTGATTCGACACGTCTCCCCACTTAGCGCGTGACCTCTGACAGGTACCGACTGTAAAAGATCTACGTGTTATATTCAACATTATCCAGCAAGTCGTGGAGTGCGTACATGTTATTGTTTGTGTACTAGAACACTACTATGACGGGTGGAGCCATCATGGTTGACACGGAAGGATAAGGATTGCGCACCCATCAGGAACATGTACTAGACACTGCGCGTTACCACCATAAGCCAGTGCCAAGGATATTGGAACGCTAGGCTTACAGTAAGGCCACAAAGATGAGACTCCTAGATCGTCTGCCGTAATATAACAACTGTACTGCTACAACGACCGATATGCGCATGGCATGGATGCGTAGTTTTCAGGGCATTCGGTATACCGGAGCTGTGCCGAAATCACCGTTTCGGCCACGACGCTCACACGATGGTCTGTGAGACAGGGGGGCTCGCAATCTTCCCCATGAACATGGCGTGATTCAAGAGGAAGCGGTGGCGTGTTCGTAGGCGGGGCGCTTTTCATTTCACGAGAGTAAGACAATAGCAAAGTGACGGCCACGATAAGGGAACTAGAGAAACGAAATTATATTACACGTGCAGTCCGGATGGCCTTGCTGATGTAGCTACATGTCCCACTATTCGCGTTGCTACAGGGGGTCTAGGCGTCTGTCGGAGATTCTATTCAGAACATATGTACAACAATCGGCTAGGACCCACTGGCTAAACGCCTGTGGCAGAGTCTCGCTTTCTGTCAAGTCTACACTAGTAATAATGGTCGCGACTGTGTGCTTAAGCGATCCCGGGCGTATCCGATATGAGAGGTAAAGGTATATTGCTCGTCCCGCCCCCATCTAGGTGCGCGTTTTTCTAGATGATTCAGACCCTCTAAGCACCGACGATACTAGTACAAGAACTCTCCATGGTACCCTCATGCAGCTGTGACGTACCGTGTAAGTATCACTGTATAACTACGATTGGGTAATGCTCGTGTACCTGGTCTATAGTTTACGTATGGCACGTGCCAACCGCGCACCTTTTAGGATTCGAAAAGGCTGCGATCGCGGATGTGCTGGCTCGCTTCACAAAGAATAGGGCGCCGTATTAGCTCGCGGCCGGGTTGCGTTCCCGCTAAGTTACTCTATGCACGCTGGTATAAACTCTAGAGATATAAAATCATGAGCCCAGGGCGGGTTGTAAATATCAGCAACGTAACAATTGTGTGCGTTCCTTGGTATCTGCGCAATCGCGATTCTGGGTTACCGCGAGAGCCCCAGGTTCCGGTTTTACAAGTACAGGGCACAAGAGAGATACAGATGAGTGCACGCAAGATGCATTATCGCCATAACTGAAATGGAAGTTCCTTCCGCTAAAGTTGTACCGCACCGAGAGAAACCATTACTCCAAGGACGCTACAACGGGCTCATCTTCCCGTCAGCGGGTATGCAGTATACTTTACGCGGCCGTCCAACATCCCAGTCTATACCTAACCTTAGACATCGTCTTACAACAGCCGGTATCCCTGTGACCGCCCTACGTACGTTGTGGGTGGAAATCAAAAGACTAAATCAATGGATTTCGATGTCGGAGTGACTTTACTCCATGTGAATAAGACCGGACGAACGCCAACTCGAATTGTACCCGGCTCTCCTTTATCGACAGATGCGTCAATACACAGCGAGATCTATGCCTCGAGCAAATCCGGACACTTGACGTCTGCGATCGTAGAAGGACGGTTTTGTTAATCGTACAAACTACCTCCAATATAGCCCCTCGTACTGTTGACAGCGATACGGTGCTATGGCACTAATCTTCACTGGCGTTTATGGGTATGACAGCTTGGATCATTTACCCCTGACCACTCTTACATACGGAAGACAAATTCCAACCAAGCGCTGGATCTTCGCCAGTGACACCAGAATAGTAACCGGGACCACACATTCCTCAGCTGAAGGAAAAGGTAGCAAGTCACTGGAAGGCCTGGGCACAGGAACGATTGCCAAAATTCTTAAACGAGGCACGAGTAGTGATCCTAAGGCACGGAAACAGCGCGTGGCCGATCTGTCGTGCACCTTGTGGTACTTTTCTGGACGAAGAGCAACGTGTATTAACTCTTAACGCTCTTCTGACATGGCTCACAACGCAACAACGTACCGTTTAAGACTCACGGACACCTAACGCTTCCAACCCCCAAGTATTCACGATGCTCCCTCCGTCGTATACCACTCGTTAACTTGATAGGCTTGCTGAAAACAGTGCTCAGGCCCGGTCGGTCGCCTGTGGTAGCTACCTTACTTTACAGCGAATCTAGCGATAAGTTACGTTCAAACAAGACTGACTTTAACGCCGACGGAGAGTTAACCAATGGACCTTCCAGCGGCGCTGACTGTTAGGTGTGCAACTCCCCATGCCAATTAAAACCAATGGGCCTTACAAAATATGATCTGAATGTCCACATTAGTCTGGGAAGAGTCATATTGTGTCCATAGACCAACTTATCAATAGCCCCAGATACTCCCTTGCGGTATGGAGCTAGCATAGTTGCTTTAGTTATTTGAGAACGTGAACTTCCTATTTGTTGTTTACAATTCTAATCGTCTCCTATGCGAACACATAGAGTCCTGACCTAATTCGTTACGTGGCTTGGAAGGTTGCACAGGTCTATAAAGCCGTAGACAGTGGTCCAGATCGTCTTTGCGTTAATTCGGGACAAATCCCTTCCAGTTAACGTTACCACACGGGAGCTCCTACACGAAAATGCTCTTGGGTGTCCTATAACCTGTACATCTACCCAGGCTCGTCGCACCCCCAGGGAAAGGCCACATCTGCGAGGGCTCTGGCGGACCGTGAGTCTTTATTCTTACTCCAACTCCCCCGAAGTAGGCACTGAAGGCCGTTCGTGTGACAGTTCGACCCAGCAGCTCCGCCGTAAAATGCTACAGAATGAGTGACCCCCCCAGTACGGACACAATAGATTGTCCCTCGTCCACCGATATGCGACGCAATTATGCTCGAGCACAGTTTGCATACGATGCCTACAGATGGGTACCACTTGGGCCGGGGCGACTTTCGCCGGGATTGCCGAATATACGTAATGCCGTCATCGGGCCATTTAAAACGGGGAGACTGGGTGGGGAACAGTGAACCCTGAGGCTAGGCGCAAACATTGAGGGGATCGGACCGTTCAAGCCACGAATCCCACGGCGAAGATATCTAGGAACATGTAATCTGACGGATCTCTTACGAAAATCAGAGAACTGGTGCATCAGTGTCATGCCTTTTTAGACATCATATACATGTCTTAGCACATGGCAATTGGGTGCACAACATCCTTGAGTCGAATTCCCTACCGGTTAAGGGGACGTACAGAACACAACATAGGAAGTCTAGTTCGATGACGATCGAAAGCTCGTGCAACATTTACATTTCACGACGGACTCATTAACGTTGCCCCGGCGTGATATACGTCTGCCACTCGGCCCGTCGTACTAAGGTAATCCACTTGAAAGAGCAAGGTCTCTTGCAGGTGACAACACGTGCCTTTTCCGGTACTCAGGTGAATATATCTCGTCCAATGGGCCTCGCCGCAACTATCACCCTCGTTATCGACGCTAGGACGGTTGGGGATTTCTGCATTGGCTCGTAACTACCATATAAACTTTGCAAACCGGATTCCTTGCGTAGGGACCTTCATTGATATGGAAAGCTGCTCATCGTAGGGTATTTGCGCCGCGCAGTTTAAATGTCTTAATGCTGCGCCTCTAACGCTGTCATAAAACGTTTTTGTGAATAATAGAGACTAACTTCCGCTATTTCAAGTGAGTCTTGCTGGTCAGAAACAG . PASS SVTYPE=INS GT 0/1 0/1 +20 900000 . C CGCCCGTTTATGAACTCAGCGCCGAACAGAAAAAATAGCCCCACTTTAAGTCCGCTTTAGCGACTCTAGGGTCCGAACGCGCTGTTTCGTACATGGCACGTCGGTAGGCAAGAACTCCCGTCCTCAGATGAAGATGCGTAATATCCTTACGTATTTTGGAACTCAGGCTGCCGAGCATCTTATTGGGAGACTCTTACCACTTTGCCCGTAAGCAGGGAAACGACATTTGATAAAGGATGGCAGGGAAGCTTTTATGCCCCTTTTCCTACTACAACGTCGAATGTTGACTTCCTGGTTAGCGTTGTGGCCTTGTACTGACCCTACTAGGGTTTCAGCTGCCTAGAGGACATTCGACCGACCCACGACCGCAGCTCGCGGTTCATACACGAGAAGCTACAATCCGCTTAAGTATTTGTTCTTTTCGTTCTAGGGCCCGCGGCACCAAGGAGGCTTCAGAAAGAGAATAATTACTCGATCGTCCCGTAAGTAGTGTATCGCTAACAGGGCCTGCGTCGTCCATACTAAGGCAAGGTGCTCCAGCAGGGCATAGGAATTGACCGGCGGGTAACATTGGAGACAACATGTGATTTGTTGCTTAATCTCGGTTAACCCGCCCCGCTGTAAAGGCGAGACGGCAATCATGAATTCTAGCACGCACCCCGCCCGTCTCTGTCTTCAAAATGTATTTTTGGCAACGAAGGATCAGCCTGTCCCGAATCGACACTGTGTTCCTATGGCGTAAAGAATTCTGTTCCTGAATCGCGGGCGCACCGTAATTCTTACTTTCACATCGAATTGTTAGATGCTGACGAGCAGAGCGCAGTGCGGCCGGGCGGAGATTGCAGGGCTGGCAGAGCCATTGGCCGTTGATGGTGTTTAGACGCTAAGCTAACCCTATGCCTCATGGATACTTGCTACACAACAGTGTCTGCGTAGGCTGAAATGGGGACGGCATGAGACCTCAGTGTCAACACAATTTGATGCACTGGGTTTTCTGCAACTACTTTACTACGGCTTTGTCCTTAACGCGTTAAGGGACTCCATCTCATCCGTATCATAAACTCCGTAGTGTATTGGGGCCAAATCTAGAATACGTACCGTCGACAATGCTCACGAGGGTTACTCAAAACTCGGCGGGGTGCCTCAATCCGCGTGCCGTGAAATGCCCGTATTCACGACGACTAAGCACTTAAGTCTCGGGAGCTCTGTTGCGTCTCGTCTAAGGGCAGTCTTGCTTCCTGTGTCTGCAAGTTCCTCTCTAGTGTTTAGGGTGCCTAATATACTCCACGTGTGTCTATGGACTCCATATGGTAAGTAATGGTGTTTGATAAACCCCTGGCCCTTTAGGTTCTACCTAGCCTAACTTCTTCCTTTGACTTTTACCCCCATTGATCCATGTTCGTCGAAGTGGCCGATTGAGGCTGCCGCATGGCCAAACCGCTAACCCGATCGAGAAGGTTGCAAGGGCGCATCCGCAAATAAACCATGGTTGCTAATTGGGGTGCAGGCGTAGAATTTGTCGGTTCAAAAGGCCCTCGACCTGCACAATGACTTGCGCTCGTAACTTATGATAGGGCCGGCATGGGATTATTCGAGGGACTCCTCACACTCAGAAGTTTACTCCCGGAGCACGACTTTACGAGGTGTGTTGCTTTATGATGGCATATAAAAAAGATGCACCAATCACCAAAACCCAACTATCCTTGACACGATCAGTGCGCGACCTACGACTACTCTAGTGGTACGACTATCGCGATGGAGGGGATATTCGTATATTTGAAGTTCATGTATTGATTCGGTTATGGCGTCTCCCTTAGTGTTTATGGACTTCATGCGTGCCCCTTATCCGCCCGCAGGCACCAATCACATTGTGGAGTTAGTTGGAGCGAAATTGGGTGGCTGTACGGTCAAACTAGAAGCATACCTTCACAAGGGCGTGGCGCTATGGGAAGTGGACCTGAGGGACACGATGGGTGAGATTCGGACACTCTGTCTACAAAATTAGGAGGTACCTACTGCTAGCGAGCTTCAAAATTCGGGAAGAGATCCTCGTACCACGTATTAATGAAGAGCCAGTGGAGCGAAGAAATTATCGCAAGACCGACCCTGTGCCGGCAGATGGACGTGTTAAACATGGTACATTGAGCAGTCCGACTCGTTGTATAGTTACCACGTGTGAGAAGACTTAGCTCGCAGCTAGTGGACAAGAACTCGGCCGAAGTTTCGTTCCTGTATTGCGCGTGTCCAGGATGTGAACAGTCCAACTTCATTATTTTATTCTGACTTGACACTGGACGTAAGTCAGCTGCTCAGAAACCGGAGTTCCCTGCCTTGGCCTGGGGGCCCCATTTGCGGATGAGCCCACAGGTCTCGTAGACTTAGGTGACGCCGGGATCTGCTGGCCTTATGTCCCTAGAAGCTTGGATGACCGGCCCACGGCAATGCGTAGTCAGGGAGGTATCCATGACGTGCGTGAGTCGGGCGAAGAGGGCCCCACATGCACCTAGAATAGCTATGTGTGTTTCTCGGGCGGAGCCCGACGTCGTCCCGCTCATATCCAAGTGCTTTTTCCGGGGGTTAAGCGGTGGCTTGGGCACAAACGGTCGCCTCCGCCCGCTTGGTCTCTCAGGTATTTCCGGGGGCACTCATAAACTACGAACGCGATCTCCGATAGCCTTCAGTTGTGGGGATGCGGCTAAATCCAAGCAATTGCGACGCTTTGGGTGTGGTGGGGGTTACTGATCCGGACTGCAAATTACTAACTCCGTCACCTATCAACACGTCTCCCTAATCTGTTGGAACCTCGCTCTATGACATCAGAATGCGAGCGCGGACATGGGACATGTCGGGACAATCTATTCTGCCTCTCCGGTACTGGGTACGATAAGCGCGACACAAGATTGTGCTCTTACTTCGCCGTGTTACCGGGTAAATCGCCGGGATGCTACTCTTATATGTGCCTTCTCACCTGAAGCCTTGCGACCTCGAATGATTTGGGTGTGAGTAAGCACCCGGGATCGAAGCTGGTAAGCACGTCACCATGTTAGAGATACTTGACCGACGATGCCCTTCTACGGCTCGGTTCACGGTGCCCAGCGGGATCCTCTTATCCCAGCCGGTGCCTAGCCGATAAAAGCTCACAAGCTTAAGGCTCTGTCAGGGGAGATGTGGGAGAGGCTCGATGAGAAGTCCTAACGACACCAGAACCCCAATTAGCACACATGGCTCTTCCGGGGACTTGGCTCTCGTAACTGCCTGCAATGTACTACGTCGCATGCTCATGTACCAGACATTATGTCCGTCCTTAACAGTCGTATTGGAGCAAGTTGTGAGTACAAACAGTACACAAGCTGTAGGTCACTCCCCCCACGTCTACCCTATATACTATAAGTCCTTGTAGCCAGGATGAGTAGGCCCCGTGTACCTTATTTGAATGCGCACCCGTGACTTCTGGTGGAGAACTTGGTCACGTCGGGTGGACCGTGTACGATACCCCACAGTGCCCCAGGAGGTATGGAACGATGCTGCCCTGAAAGGTGGAAGGCCGGAGTTTTTGTAGTTACAAACAGTACTCAGCGCTATCAGCAAGTGGACACGGAGAAGTAATTGAATGACCGCCTAGCAGTGCTCCGCCTCCGGGCGGCAGCCCGCGTGCCTCAGTCAGAGATCTCGAGCACGCACCCTTGCTGCTTCCGACTAATGGGAAGAAGTGGAGATGGCGACCCCCACGCGTTATAGTCCCAAGGTTGCTTCCAGGAGCTATACCCGAACCTTTAGGTCTAGACTTGTCGAGTTTGCGACCGTACTCGCTTTGTATGTCGACTTTTTTGAAAAGACAACCGTGGCCCGGTCACTGTGTCTCCAGTTTGGCGAGCCGTAGTCAGTGATCGCGCTGCTCGGGATCAATTATCTCCAACGGTCAGCAGATCTACGGAGTCGGTGGCCGGTATAATGCTGGAGGCCGGTGTATGCAGGAACCTAATAGTCCCCGAGTGTCGATCTGTACGGGAGTCACTAAGATAAGGCAGAACTGACTATCTCTCCACCGCTACGTAGTCCAGTGCCAAGGTGTGGTCATGGCCCACATAAATCAAGGATTTGTATGCTAGAATTACGCGATCGAGTGACACTCAGAGTGCACTGGCTAAGGACTCTAGCTTTGTAAAGACAGCATTACATCAACACTCGTTGCATTCCTAGACTGCGGTTCCTTCGGGATCTCCCCTTGGTACTTCCTATATTTCCTGAGATGTGGGCGCAAACAAATGCCAGATCCCGCCTGTAGGCATTCGGGACGGGTACTACGCGATGACCATATCGAGATTGAATCTTACGTATCTCCCTACAAGTGTGGCTTAAGGGGTTAGCACCGACAACTCATATAAAAACCAAGTAAAGAGAGTAAACACAGTGCGGAGTAGCCGTACTTGCGAAGCGCCATTTGGGCGCGACCTTCCGAATTTGCATCCGACGTCGGTCGTATAGCAAAGAGCGATTCTGAGCCTCCAGTCGCGGCCACGTCGCCGCTTGGCCAATGTATACCAGTTGTGAATAGGTCGCGGAACGCTAATGGAAGTAACCCCTCCTATTACCAACACGCCTCAATCGTACCACCGGTACCCACGGCATATAGAGACTATACGGCGTCGCGGCGGGCCTCCTCATGCTCGTATGGACTACACACCATGTCCTAATAACCTTGGTAACATTACGCCTTTGAGGGGTTCTTTATCTCCGATTTCGCGGTAGATAAGGCCACATGACATTTTCCGTTCGAGCGGACACGTGTCGCCTCAGTAGCCTATTGCCGTCGCCCAACCTACGCCACTGGCTCATGCCATGCCATCTCATACAATTAACTCCCGACGTTCGTACCAGGTGTACCAGGGGGTCCATACTAAGAGAGTGTGACCTCCAGATTCTAAAATACTATGTGAGGAAGTCATGATTTCCTCTAGTCATTGTGGCACCGCTCGTACCGTGAATCATATCAGATAAGAACGATCAGTTTGCGACTGTTATTCCGAGGGTACAGTCTTTAAGACACCATTCGGAAACGAAAAGGGACTAATGGATGCCGCGAAAAACCTAAAAAGGAAACAAGCTATCGATCTGTGGCGCCAAGGAGGGCGGGGCCCCGCATGACTCGTCAACTCCCATAGGCACCGCTCCGGGCCGGTAGCGACCGGAAGGCAATTGCTACCCTATCATATAAATGATCCTGGTCATTAGTTGTGCCCCGTATACTTGAGTCAAGTATTCCGTCGCAGAGACTACTGCTCATCCGAGACAACTTCTTCTCTAAGCGACCCGGGCGGACAAATTCACACGCAGATGGGAATTACACTAGGGGTATACTCACCCGGGCCTAAGGAAGGCACATGAGTGGGGCGGGCTGATTAGCAATTGTATCAAACTAGGGTCAGGCACACATAATGAAGGAGCAAATACATTGCACGGATATAGCCTAGTCGAGTTCGACGCGGAAGAGGTAGGCGAAATAAACTGTGAAAATGGGCAACACCTCACGAATGGTCATGAGTCAATGTAAAATCTTCGCGGCTTACTCGGCCTATTGCTATCGTGACTCCCAGGCCCTCAGTCCACCTCTCGTCAGATACTAGTTCGGGAGGCTCGAGATAATTGACCCTCCCTAATTCAAACTCAAACGAACTCACGTACGGGTAGGGCACCTAATTCGAGATGAAACATGCCTAAACGCCTCGAGAATATGTCTGTTTTGTACATAGTCTGTCGCTTATTCCACCACTTCAATCTGAAAATAGCGGACTAGTCCCGAGGGCCCCGATTTGACAGGTGGTTGAGAAGATCAAGTTGCACGCTAGCACCAGACCCTAACTCGCAACTGCTCTGCCTGATAAAAAACACATGAATCTGCGAACCATAACCTTCTTTGCCATTCTTTGTCTGCGGTTAGCGATGGGGGGTGTAAAACCACCTGCAGCGCGTCCCGATGATAAGCTATATGGGTTCACGTGCAATCCCAGAATCCTTTGGGGGGTGGATCAAATTGAAGCGAACGCAGCGTTGTATCGACGGTGAGCCCGCACATTTGAACTCGTTCCTCGGGTTCTTCGATGAATGTGGACTACGCTAGTTGACAATGCCTGCAAGTCTCCTCTCTCCCCCACGTGTAATATTGTACATAGTCAAGAAAGCTACATGCACGCCGACGTATCTTCTGTGCTTATGGATCGTTATAAAATTTTGTACTTACAGTGAAAATATGAAGGATGAAGCCTTAGAACTCGCTGCGTGAGAGAGAAACCCACCTATAACAAGACGCACGTGGCGCACATCCGTCCCCAGTGTTCAGCGACAGTTTGTCTAGCCAGTGAATCGGATCAGGCGGTCCTAGAGGTCTAGGCGACTTATGATCTTAGTCAGTAACCCCAGTAATTACCGTGATTACCATTTACAACGGTTAATTGGGTTGGTCTATGGTAACGCACAAATTACTCGTCATACCTGCTTAACATGCCTTCGGGAGTTAACGCTGTCGGGCGGGGTCAGCTTACATTACAGTAATCCGGCAAAAGACAAACCAATGCATCTCAAGAACCAACATAATAAAAAGCCTTATCAAATCTGGATCACAACTAAACGTATCACAGTAATATGTATCGCGAGTCTAGGAACTTGAGCACCCAATCATCATCCGTGGCGTCTCCGCGGGCTCTGAACGAGAAAACTGGGCACTCCCGGCTACTTTGAAATCAGGAAAAGGTCATCTGTTAAATGTCTGTTCACGATAATAGGCTATTCCACTTCAATACATGAATGACTTAGGATAGATATTCCCCTGGGCACGATGTTCTTATGGAGTGCGGGATTTAGTGGATATTCACGCTTGTATTCAGTCCCCTGTCCCATCACCTTTTTATTTGTCCTCCGCCCGGATTCGTTTCGTGCACGGCCAACGAGGAGCTGTTCATCAAATCTACCGACATTAATAAGTCTGGCCTATATGTCGTCCAACTAGGGACCCCTTTCAGAGTAGGTGGAGCTATCGTAGTCATCAAGTCACAAAATGAGTTCCTTTAAGGTGGCGATGTGTTGGGTGCAGACAGTATAGATAACACTCGGCATGGCTTTAGTCCCTCTATCTCGGATGCGCGCATCACAGATACCGCACAGGGTCCCACCTTACATGTTCGGTTGGGACTGAGTGGAAAAGTTGGACCCTAATGGTTGCTTCCGCGAGAACAGAGACTTGAAGCAGTCAGTCAGGGATTCAGTCCGTCAGATAGGGGTGGAAGTATGGCCGGCGGCCATTTGAAGTCGGCTAGCAGCAAATAAATTGCGTAAATATGTTGGTGTTTGGGACAAGGAGGCACGGATCCAGACGTTACTGAGTCCCCGAAAGCGTTACTCACGGATACACGCCATACGCTCTACTAAGAAGAACCATGCACGGACCATTCGATACAGTCTTTCAAACGCCAATGAACCAGGAGCCGGGGGGATGAAGGTGGGTTGGAGGCATCGGAGTGGTTGGGAACTGGTAAACGAGAAGGCCTAAGAGTACTCCCAACGCGGTGGGTAGTATGTAGGTTGGTTTAAGTCGCGTTATCTGGAGCCCGATACAGAAGACCATCAGCTAAGAGTGGTCGTAAGACAACAGATAATCCAGGCATACTAACACCGTTTTATTAACACCTAACCCGTGCGCGGGCAATGATCTGTGATTTCGGCGGAACCCTTTAGCAATCACTCGAATGCTCCCCTCAAATTTGAAAGGCATGACCTCCGTTGTACGCCCTGGATTTCTTAGGGATCGATTAAATTGGAGGCGAATCGTGTGTCTGATCTATTGGCCAATTTGATAAATCGGGACAGAAAACCCTGGGCAGCTGTATCCCGGCCAACTTGACTTTCACCTTTATGCTATCAGAAAAATCGGTGAAACTGAAAGTCTCTGAAGTTCTCTGCAGTCATGCGGGTACACGAATGTGAATATGAGCTGTCGCGAGTTAATAGGACAGGCAGAAGCGCAGGTTGCGTCCTAACAGGAATACTCTTAAAGTAGGTGCGAATCGAGCAACGTCATCGCGTCAAGCGCGACCGCTTCAGTTGGTTGGAGGCTGTCGGCAGGTTCATCTTGCCAAATCGAACTAGCAGTGGCTTCGTTACGGGCCAATACCACCTCGAGGAACCCGGGTAATGAGGTACAGCTTACACAGGCAACCTGACAGAATGGATGTTTGACCTTCTATGCTGTACGTGTTAGCCCAACACAATTAGCAAGATTGCACCGGCGCTAACAATGTTAATGAGGTGTACTAAAGAGGTCGTACAGACAGGTCATGGGGGTAGGCGTATTTTCGCGCAGAACACGGGTCTATCCCATGAACGTACAGGCAAAATATTCGTTCTAGGAGCTGTGGGTCGGTTCCGTGGAGAAAAGTCGCAAGGCTATGTAAGCATTCATGCCTAATCCTCGCAAAAAGTGTGTGGGATTAGAAGCGTGTCTGAGCAGATGTGGTGCGGGATCGAAATAAGTAGGTAACTACCACAGCACACTATTCCAAGCAATAGTTCGAAAAAGGAAGACAAACCGATTCGGTTAAACTTGTGGCGGTCCTTTATTGCGCTAGCGTGCACATACTTATAACCGTTCCTTGCTAGATGCCAATACACGATATTGGCACATCAGGTGCTTTCACCCGAGACAAACGGCCTCTGCTAGCAATCCCGGGTCGGTAAAAATAGAAGACGAGAGGACGGCGATCATATCGTGCGAATAGTATCAGGCTTCATATGGGCAGTTCGCCTCGAGGACTACCCTCGTCGAAAAGCTTTACCGGAAGATGCCAAACCCGGGCAGCGGCACCAGGCTGTTACCCGTACTCCTAATAGCTCGGCTAAAACACGGAGAATGAAATACCTGTACCAAACGCACGTTGAGCTTCATCCACCTCTGGCGTGTGTACTATCCTATAGCGGATTTCGCCGGAGTTGCCTTTTCTCCTTGAGTGTTGATGCTGCCTTCTAACAAGCGCCTTTGCACCCAACATCGACATTTAAACTTTATTATGGGGTTGGTCCTGCTCCGTGCAACTGTCCTCTCTGTCACCACTATATTAAACATAGTCTGACCTAATGCAAGTTAGTAAGGAACAAGAGCAGCCTCATAAAGACTTGGCGACGCGTTGAGACACATATTGGGTACTTTAGGGATAATAAGTGTGAGGTACGAGGTGCGCGGACATTATCTTGATGCCCTTCTTGGAAATGTCGTATTTCAGGCCCCTGGTGCGGAAGAACTTTGGCCGGGTTTACATAGTTTAGATAGTCCTAGGTACATCAAGACGCCAGTATGAGTCCGCGAGCCGGTATGAGTCATATACAAGCCAAAGGGCCGCCTCCAACTTCTGTATCCGTAATTTTCTCCATAGGGCTCTGACCAGTATTGACCCCAAAATGTGGGCTGCAGATCCAAAGAGTTAACGGTACTACCCGAGGGATCAGTCATTCACTACGGTGCGCCTTGGATGGGATCCTACCGTTGAATTCGTAGCCTCCTGCGCTCCGCTAACCCTGACAATATGTGCACTTCGCCTGGACGTATTGACACCTGAAACGAGCACTGAGCGTAAAGCTAGTTGTTATACGTCACTGCACCATGTGGCGGGTTATAGCATCCTCCCATTTAGGTAATGCGAATCTTCACAGACATGACGGGGCATGTGGACTTACCGGTTACTTCGGGAAAACTGGCAGACAAAGGTTGGTTATAACCTACCAGCAAGTCATAATCTGTTTCAGGAATTACGCAGTTCTGCCGCTCATCCTAAAAATCCACCGACCCTCGCACGTGCCGAGTTAATCTACGGAACGCATAAGAGAACGGAAGCCCAACTGGAAGTTGGACAATGCCATGAGCGCCCTCGGACCACCCTCAGAGAGGTAATTTAGGGGAGCTAGGTAATGATCACGCTTTTCAGTGGTCCTGTATCGTGCATAGGGAAACCACTCTGGATAGTGCTTCTAGCGAATCGTCTAAGTACCCCATCCTTATAGCCCTGCCAAAGTGCTGGTAGTAGCTATCCGGATCACCACGTTCGGGGGACGGGGCGTGGCTCGTCCGTATGCTGGCTTCGCCGTAGCGCAGTCCGAAAACTGACAGACATAGTGCATTAGCATTTAAACCACCTCGAATAAGATTTGGGCAGATAATAGCGCCATCGTGTGCACTTGTTGCTCGGTGCCACCTAACCCCGAAGCTCCTAAGGCGCGGGCCTATAATCGTTATCCCCTACGAAATGCAAGTGCGTCCTTGCTAGAATCATTTGACTCTCCAGGGCCGGGAGTGATAGACCTTTTCAGATGTGTACCCAACGATGGGTTCCTACTCACGTAGATACCAGTTCAACCGCATAACCGTGAATTTTGGTCCGTGTCGTGGACGCCCGGAATGATAAGCCTCAACAGATTGCCTGTTTAGCTGGTCGATTGTGCCGATCAAGTTGACGTGCTAGGCCGGCGCTAAGCGTAGAGGAGAAATCTCGCAGCTTCGATACACGCGAGAACTTGGGCGTCACTTACATAGTCGGAGGTGTCATGGTTGAGCCGGTATCTCCGATTGATCACTCGGGACCAAACTCTATCTTCCTTCTAGAATCATCACGCCGACTTGAACACTGTCGTCGTTTATCACTGATAACGCTTATCAGGTTACGTGGAATCGAAGGTTCAAGACGGTCATGGAGCTGTTTTCTATTATTTCACTGTTAGTTCTTGGATACTGGCGAAGGACGCGCCACTTAGACTGTGCAGTCCCCAATTGGCTCGAGATTCCATCGGCGCGTCTACCTGACTCAATGCGTTACAGTCTTGGCCTGGCGCTCCTACCCCTGCGGCCTATAACGAGGTGGCTGTCCCGCGTGCAACACTCGCGAGCAACATGCCAAGACTTAGGTATAATAGCTTAAAGGTGTTCGCTTCTTGGTAGATAATTCTGGATCCGCGTGCCCACCTCCCTGTGCTACGAAGTTCCGTGAACAATGTCTAGATGTATAGCAGTGTGCAAGCCACCAGGTTCTATGGTGAGCAGCAATACAAGCCGTAGGTGACGTTCGGAATGACCCGCAATTTGTCGCGCCCCAGAGTAAAGCGAAGGCTTGACACTCCCGACTAGTAATCCCATGTGTAGGCCCCAGCACTAAAACATCTCGTTCCTCCTCACTTCCTGTGCTCAAGCCGCCTGGGGTCGAGGCGTAAGTACGGTCTTGATTGGTTGATTTTTGGACAATATGATGTCTCTACCAGCAACGCCGCCACCGGTTATGTCAGTCTCTGAGTTATAGCTACAATCTCAAGAATGTCGTGCGGCTCCCGTGGATGGCAGACGAGTCAAGACCAATAACAGACGTGTGGCACCTCTGGTCGTATCGTCACCCCCAATTGATGAAAATGTGGCTAGAGTTCCGAGGAGGACTTGCAAAACGAGTATCATTGATCCAGCCCATTACTCCAGTGTCCAAGCCCGAAACTGTAAGAGGGCCATTGAAATAATACCGGCTAAGGAATGTCTCGGGCGTGCGGGAATCATAAGGATCCCTCAGTTGACGATTGGGCGCCTCTTTTGCGAGCGGCATCCGCTGCATCGAGGTAAATATGTGTTGGGGACACAAGCCGGATTGGCATTGCCGGAACTTATGTGCGGCAATTGCAAAAGTCGAGTACTAGAAGGATGATCAATTGCCGATGCGCCAATTGAAGATGATCGCCTAAATTGGCTTGTTCATCCTTCGCTCCTGTACGAAGAACTCTATCCAACAGTTGATGGTTGGCAGTAGTTCCGCACGAACAACAACGGGATGGAATTCACGGACATGTTGGTGCCTAAACTAGCGCCGGTTTACCGGACGTGTCCGTACTCATTCCCGCCGCGCCAGCCAGAAAGGGTCGATAATTGCAACCTCTCTCGCAGTATCCTTTGGTCGGCAGAACGCCATGGAGCGATCTCCTATCTCTCAAGGTCAGTTTAAGAATTATGAAGTACTTCTCGACGTGTTGAACTTCCGGTCTCGGCCGTTAGGCTCGCTCGATTGAAGTACAACAGAATTCAGTTTAACCTACTACTCGCCCCAGAGTACTTCCTATGAATGGCTGAACTCTGACACCGAGTAGACAAGTGGTGGATATACTCTTTACGGGAGTCACGTATATCGTACTATTATGTTTCAACGGTGCTTGCCATCCACCACAACACCGGTAAGATTATCAACGCTTACTCTCAATATTGCCCGCGAGGAGGTCTTATCCAAGGTGTAACAATAGTAGTCTGTAGCGTTGAGATTAGTCTTAGAAACGGTGAAGGGCGTTCTCGTGCGCTCGATACCGCTCCCCCCCAATCGTGTTCGGCATCACTAGGACATACAGCGGTCGCCAAAGCCTTTCACCGGTATCGCTTCTCGGGACTGATGCTGCAATACACGCGTAGTCGAAGCAAATTTATGGTGCCCAGCATCTGAAGCAACTCCATAACTTTTACCGTCGATAACAGGATTTGGTAGTCCGCTCGGTACTAATGCCGCAAAATGAAGCCCTATAATGAGATATCCTAAGGACGTAGGGCGCCATTGTTGGTTAATTCCCCCTACGGATTGACGGGCCGCGCCGTCGGGCTGGGGTTCGTATGAACCTAGCTCCACGCCAAGACCTGTCCCTTGTCATAGCCAACAGGACACCTTTCATTATGGCGCTACGCATATGCGACTGTTCCCACAGTACAATGATGTGCTTAACCATCGTCGCTCGGCGATAGGGTATCTTTTAACTATCTTAGACTGATAACGTGTGGGCCGATAGTATCTAAGAGCTGTGAGGCTTGTGGACCACTTAAGCTATCGACTCCCATTGGGGCAAGTGATTACCCGGGTGCTATCCACAAGACCGCACTTGTGTCCTTGCGTCGAATTAAGAAAGCTATAGGGACCAGCTGATATTAGGTGCTGAGGAGTGCTACCGGCCTGTTTCACATATATCAGAACGCGTGCCCTGAACTAAGACTCAGCCAATCAATACTGCGTTGTGGGTGAGGCAAGTATTCTGTCCGGGGATGCTGTGGGGGACAGTATTGATCTATCATACTAACCATAGTCGACATCTCAGGTTTTCGAGCGCTGACGGTACAGACAAATTTAGGGCGCTACGAGAACAGCATGTCGCTTGAACCGACTCAGGCGCCGTAATTAAAGGGAGTGTGCCATGAACTCGAACGCACTCCGTATCAACGCAGAAACCGCCTTACAACACTGAGCGGCGTAAGAATACTCACTCGATATTGATTACCGTAAGGCTATATTTGTATGGGAAGCAAACGAATGACATTTCCTGGATATACAACAGTTAGCTGAAGGCATATGTGATCTGCCAGATTCCAGAAGCTGATGGGGGATCAGGATGAACCTTGTCAAGGATTCGTATCTGCGCTATACAGGGAGAACTGTGCGATTGTTGAGGCTACGCCGCGTAGCCGAGCCGTTGGAATAAGCAGCCCCGTATGTGGACATTGGTAGGAGCATATTCAACGGGCCACTAAAGGTCGCAATTGCCTACATCAGATGAAAGGTTGTTACCGGGCTAATATCATATAGAGCCCTCTAATATCCACCTGTTGTATGAATACTGTCGCAGTTTCATCACGGTTGCCCCTAAAACACTGACAATTAGGTAGCGGTATCGTTTCTCATCTACTCAAGGCGTATCTTGGGTCGCAGGGGCACGCCGTGGTTGCTCGCCAGTTACTTACTGACGGTACCTCTCATTCTTTGCAATGCGGGTACTTGTGTCGTTGAAAGTAGTGGTACTCGCACCAACTCAATCTATCGCCGCTGCGAGACAGTCCCCGAAAGCCTCCGCAGGAGCAGCGCTACCTCATATCCTGCACGATTAGAATTAACTGCCTCTCTAGAAACGAGTCTTACTAGTAGTTGACCTTGATTCTACGGCCACTCGCATCGCGATGATTGAGAGAGTTCCCCCACTCACGAATTAGGAATCATGTTGTAACAGCGGTCCCACTTGAAGGTGAGTCTCCATACAACGAGTACATACTTGAGCAAGCAACTAGATTATCAAGAACACGCATTTGTCCTAGCCTGAACCACTTTTGGTCTCACATAAGACAGCGGGAGAAGCGATTCGGGCGACGAGGCTGTTAAGTCGCACGGGTTGCTATTCATATAACACCTCGCCGTCGTGTTAATGATGTTTATGAGCCCTGGCGGTATGCAGAGCTAATTGGTTTGCATGGGTGAGGTAACTTGATTCCGTGTTTGGTAACGAGCGGCGGTCTACACCTAGTCTCGGCCATTGGAGACTGTTCGCGGGGGTAAAAAATCAATTATACAGACACTCTAGCCTGATATTGCCCAATTTGAAAGAGTTCAACCTTTCGCAGTTTAGTGAAAACTGAGCGGTTTGTGAATATTACCGGCCTTATATATCAAATGGTCCGGTACCAAGCCTAGACATGTTCGGACTTTGTTCCGTTAAAACCGAAGATTACGCATTTCACGACTCTAATTTTTAGAGACTGCTAGACAGGATATCAGCCACGGTGCGTCCTTCCTGTATCGCTACGTACTTGCTCCTCGCCTTCTATATAACGGTACTGGCGAATTCGACAATACCCTAATAGGAGCTGCGACTCTCTAGACGACCAGCATGCAGCTTATTTAAGTCACACAGATCGTAAGAGAGCCTCGCAATGCTCAGGATATCGGCTGCCCTAGAGGATTAGCGGGAGTTGGCTGGCGCTATTGAATGTGTCAGCAATGGCAGCTCCAGGATCGTCCAAGGAGCCGCTGGCCCGTCCCATATGGTCTTCGTATCAGTACTGATCAAAAGGCGCAGCGTGAATACGTTTTCCTCCATAACATCCAGTCAGTAGCTGATAACGTTCTCACCCACTGACTTCCAACAGGGGCGATGGACCTCCAGGCGAGCCATGGAGTTCGACCCCCTTGAGGTATAGTGTAGGAACGGGATAGGGATTAAAAGCGTTGTGGTTTACTCTAAGCAGGCTAAGAGGCATAATGTCAGCCCATCAGCGCGCGGTTAGACCTAGCCGATTGGCGCGTACCAGGAAGCCGTCCGTCAATTTACAATTGGTCGTAGTCGGGATACCATCTTGAAATGCGTAGTCCGTCGCGCTTCGGGGCGGGCTTGAAGTGATCATGTGCACCCTTTAAAGCCATAGCCATACAACGTACCTCGGCTGAGTAGGTTCATTCTCTTGGAAAAATACCGCTAAGATAGAGACACCTAAAGTAGGCTTCTTAATAGGGCATGTGTTTCCGCCTAGCGTTGACAGCATGTGATTAACCACTTGACCATCTGTCACGCGTCATGCTGAAGCTTACCCTTGATACACGGGCCGTTATCCAGACGCCTGGAAACTCGAATTCATCAAAATTCCTCCATTTCTCTGGCCCGACAATCCACTGTAGAGTGGGATCGGTGTAATACCCTGAGTTTTCTAAACGGCGACACCGATGCTATTTAGTATGCCACGCGCTTCGTACTGTTGAAAAGCAATTGGAACTGGATGTCTATCCCGTACTTTTAAGTCGTAGATCCGCATCATCCATGCTAATCGTCGTCATTAACCAATCACAGTCTTGCAAAACTCACACTGGCTGATTCTGTCCAGCGTTACCGCGGTCCTGTCCGATTAAGAGCTCTCTCTGCCTATTTTCAGTTCCCTCCAGGCGTAAGGGACTTGATGTACACGCTCGACGAGTGCGGCTCTCTGTGACTAGAAGTCACTCGGGCTAAAGACGACTAGAGGTTTTTTCTGCGATCTAATATTAACCATACCCTACACAAACGCCCACCGGTTTTTATCACAACCACAGTAGCGGAGACGTAAATCGTTGTGCACAGAAAGTTAGGTAAGTTATCAAAGGGCAAAAGAATTACAGGCCATATTCTTTCAGTGTGACCTTCGAGTGCGGATTAAGTCCGCGGCAAAAGCCTAGGGACGACATCTTAGTAGGCTATCTCCACCCAGTATCTGGCGCGACGTCAGGTGTCAGTACCATGCTCTTATGCCCCCCTTTAGGTCCACCTAAACCTCGAGGTCAGCGATTGACCCATGTAGATACTGGTAGACGTCGGTGCCACTATGATCGGTTTTGTCGTAATTCACGAGCATTTGTCATACTGTTAAAAACAAACTTTGACGACAGTTTGGTGCTAATTTGAGAACCCACGTGGGGCCTGCCGCCGGATGTACGGTATGATCTCACCGGGTCTCCATGATACCCCCATCAGCCTCATGTTCTGGCCCGTCCTCAGAAGCGAGCCCTCAGTCCTTTCTTAATCTCCAGTTACTTATCAGGGAGTCCAGAAGCTCCGGGTCTTCCAAATCCTCCGCGATGTCTTAGTCGACCCTAGGGACACCTAGAGGATAGTCGCATTTGTAGTGTAGCTGTCCGAGAGCAGAACGCTGCGGCAGGCGGACATTGAAGTTACGGCTATGTTATCAGTCATCCTCGGCTTATAAGAGGCTTTGGGAAAGTTGGGTTAGTGGCCCAAACGATGATATGCACCAACCAAACTCTTTCACAGCAATCCCGCAGAATAATTGCGGCGCGGACGGGCGATGGGCCAGCTGCTAGGGTAGCGACAAAAGGACCACCAGCTTCTGTCTGAAGACAGGGGCCACCAAACCACCCTTGTCCAACTCGTATGCCCGAACAAGAATCGAGATCGAATTGTCACTTATCATCCCGTACACAGTAGGTCCCGTCTACGTATTCCATGCGTTGCCGCAGGATTTACACCAAGTTTGGTCGCCGGTCCTCACTCGCTAACTACAGCTGTGTAAAGCGCGGGCGAGGGCGATGGATACGTACCCGAGGTTATCAGGCTGAATTGCTGGTGAACACTTAGGTACGACTCATACGCGGGAACCCGGCAGAACTGTACATTCGCGGTTTTTGTCCTCTAGCTATTTCCAAGAGCTGATCACGAGAAGTCTCTCCACGCACATCGCTGAAGCGAGACCCTCGCCAAGTGTTACTTATAGACTTCTATGCGGCGCCGCAGTTTATACAAGTCCTCGCTCATTTTAGTTCGTGCCTACACTGTCACTCCTACGGTACGCCACGGCGCGTGGTGATGAAAAGGTTTCAAGTTCGTATGCGAAAATACAGGCCATTTAACACGGACTCCGCGTCCGGGCGGGGCCGTAACGTTGCCCGTACCCGGACAGTTCCATTGTGAAGCACTACAGCTTCAATGTTACCAGTGTAACGCCAGCATCAAGAGTTGCAATGGTCTAAGCGTCACCTGAATTTGCTATATCCTGACGAGACAGGCGTGCCCCATCGGAATGGCAGAGGTAATAGGCAGCATCCCCGCGGATCTTCATCTGCCGTCAACAGCGCCGGATTTGTAGGCGGGGCGATAAGCACTCGGGGGTCATCGTTTAACCACCAAATGGGCAGTACAGGTGTTCTCCTGTCGGGCCGTGTAGTTAGTCCGACAGGTGAAACAATCTGTCAACGAATTGGCGCCTACTTGGTCCGCCAAGTGAGATCTTGAAATTACAAGTCTTTCCGGCGCAATCAGGCCACGATACTGGGGCAACACCCCGTTGGGACGACTGGTAGAAGCTGGACTCCGGGACGGGGCACAAGGCGGTGGCGGCATTGAACAAGCACGCACGCTCCTCCCTATACCTACGACAACTTAATCTTGTACCAGACAACCTAGGAACCCTCACTTGACTGCTCAAGCCGAAGGGAACAACCCCCTCCTTGGACAAAGCTTACTGCCAAGGCTTGGTACGTTCGCGTGTCCGTTCTGTATCGGGACCTGAATTGCGTGTGCAAGCGTCATTCGCCATGGCCACTACGGCCTGGTCGGGCACCCAGTGTGATAGTCTTTCATGCGAATGGCCCAGTGCTATCTTGTTCGCAACGTTCTGTAGATAGAAGGCCGTGGAAACTGCGACTATCCGCCGCACAACCTTCACGGGCCCCGCCTCTCTATGGAATACGTGTCTCATGTGCGATATGAAGGTTGCCCTCCATAAAGCAGATAGTGCTGATGTGCACTACTTGGTACTTTGAAACGTATTAGTCTCACCTGCTGATGATTCCTTTAAAGCGGTGCAAACAGCCTTCGGCAACCGGCCACTTAGGCTCGACGGACACCATGCCTTTCTGACTTACAAAATGACCACGCCCCTACGACAGCTGTCGTTACCAGGCATGCCTTAGCTGTCAATGGCCTCATCCTGCCTCCTAAGGGGGTATGTTCTCCTAGTAGCCATGTCATAAAACCCCTGCGCGAACCGGGTTATCTACGAACAGTACGAACCCGGCGCGTTTTGGCTAAAGTGGGGTTTATTCAGGGAGCCCGACATACCACAACAGTAACAATAACACACTAGCCGTTAGCAGGGTCGACGTGCTCCCGTTCGCGGAATTCTGGCTGAACGTAAATACGCACCTGAGCGAATTTTCCACGAACACTTTTACATTTAACCTCGCAAGAACCCTCCCCATTAACGAGCTGAAACGCTTATAAGAGAGACGTAATGGATCAGAGACCATCTCCTCCGAGAAAAGTCTGGGTGAATCTACGATGGGTATCTGGAACCATGCTCCCTCTTCCGGAGGACAAGCCCTTAATATGGAATCCAGACTAAAGCCATAGCGATAGCAGCTTAAAACTAAGGCACGTCGTCCAGCCAATTCGGCCGATTCCGTTTGGAACAAATAGCTGTCTGTCGCAAACACGACCCTGGGAAATGATCCAGTTCTACCGCACCAGAAGCGACCCACCCCGTATTCGCGTGGTGTTCCTTCAAAAACGCCCCCTTGGGACTCAAGACGTCGAACTTCTTTACCCCAACCGTTGCGGGGTGTGTGAGAAACCGCAGACTTGAGAGCCCGAGTATCTAATGCAATCTTCTCGGGTAACAAGTGTGTGTACATCGTGACAAGTCCTTGGGGTCTGCAACAGTATGTCCGACCAATTGACCGACCGCAGCATAGTCACAGTCGGAACTTTCGGAGTAAATCCAGGAGGGACGCCTATAAACTGTTCATAGGTGTCAAAACGGGCAAGGAACCAGAGAATGATTCAGTGCATTCGAAGAGTGGACGCGGTAACGACGTATAAATTTCGCGCTTCCAAGTAACACCGGACCGCGATGTGTGTCGCATACCGAGTTCTATGACGATGCTCAGAACCTTTGTCCACTAGCTTGCAGTTGCTCGACCCTAAGCGTTGATCCGATCTGTGTACAGAGAATCCACTTCTTATCTCCGTTGGCCATTAAAGCGTTTGTGTCCAGATCGGACTTGGTGTGTATGTAAGGCCTGATACCGCACAATAGGAAATATATCGGCTAAATTAAATTGGCTCGGGATAGCCGATCTCGAATACGTCCATTACTGAAGCAATTGGTTACGCGCGAGCCCCCGATATTGACTTTGATAGTATGTCCAAACGAGTACAAACTCGTTGCACTTAAGTTCGACTTGCTATGAAACATAGCCGTAGGAGGATTTAACCGAGCCACAGGCGGCTCCCTCTATCTTAGCGGATCGAAGTAATATTCTGTTGTCATGGCTTTAATTGGGAAATGGCTGCCGAAATTTGGCGAAAGATAACAAGTTAATAAGGACAATTCCTACTTACCAAGGGTACTGTTTCGCAGCGGCCGGTACCCCTTCGAGACTCTGTTGATTTTCCGTGTACACAGGCAAAATGCATTGTATATCCCGGATTGCTTGCTGCTCATTAGGACTTTACGACATTAAAAGCAGACCAATTTGACCCTGCTAACCATTAATCAAGGTAAGCTGCTCTTTCACGGAGAAAGCGCGTGTCTGACTGAGTATATCTAATAGAGTTAGCGTACAGTAGTGATTGGCATGCCATCGAGAGGCGACGTCCGTAGTCAACCTACACCGTTAGAGAACCCTTGTCCGTTGCGCTTCTTAATCTTTTGTCGAAGAGGAAGTACATGAAACAATCAGATTAGTCATTATGATACACATCGGTTGGGACACATAATCTTTGCGCTGCAATACCCTACAGTGGCTGAAAGAGTGGCGTTGCACGCGGACTAGGATTACAGCGTATGCCCAGGTTCTTCGTACGTTCCTATGGGGCTGTAACTTAGTATCAGACAAGCTTGCAGACCCGCGCCCGGGCACCGTGCTATCTGAGTGCATGCCGTCGGCGTAAATCGTGCAGTGATTCTCCTCCGCCAACGGCCCTGAACAGGGTTCGGTGCTACTACTGTGGCAGGGGGGCGGGGTGTATGTTACCACAGAAACTCCTCACGCGGCAGGGTTGACGGCCAGTATACGCTATGAAAGCCAACAATTGGAGTATGAATCCCTCACGAGGCTTAGCGATGCAGAAGCTCGCCTGTAGACTAGTCTTACTAAGTGAAGAAACGGCGGACGAAATCGAACGTGGGTTATGCTTCGATAGTCAACCATGAGTGCATTCAGTAGAAGGTCGGAGAATCCACTAGTGTGCGGAATTATGGGTTCCATCTAAGGCGAGAAGGGTCCGGGTTAAGTCCAGCTTCTACACTCAGCAGGCAAACATACGTGGCCAGGCTCCTTTTAATCCCCGGAACAACCCACTCCGGGGGGTGATCCCGAAAGATAGATTTATGTTGAACAGGCAGTAGCGATTAAGGCAGCGGGAGTGGACATATATAGCAGCAAATTGTCTCCCTCGGGCCTTAGCTCTAGCTCCGGATAACATAACATACCTGTGCATTTGGCAGCAATGATGATCTTGTGCTAGGTTGACACTGGTTGGCGGACAACGCCCAGTAATGGGACTAGCCTGTGGCAGTTTGAGTTTATGCGTGAGCACAGAAGCGCGCCCGTCTTAGGTTGCTTCACACGGCCGATGTCACGGCAAATTGGTTTCCAGGGAGAGATTGACGTGTCTTGAGTCTACGCTCCGCGTTAAATACACCCCCCCTGACCACGTTATTGTGCGTTTAGACCTATTCAGTTCAAGGCGTATGGGAAGACAGCCCGGTAACGTCGCGGTCGATGTCGAGATCCGCTGCGCCCGTTCATAGACGACAGCATGAGAATCGACGGTCTTGAACGTTAACAGATCTCAAAGTCGTTAGCATAAAGCTCCTAGACCAGTCCGTATTGCCGAATGTCCTTAGACTGATAGGCTATGGCTGCAGACTCACGCATCAGCCCGGCGGGGCTTCAGCGATCTAAAGCTCGCTCCGAAGAAGCTCGGGATACTCATGAAGGGAACTTGAAGAGTTATATCGAGCACGGAGAGACCACACATAGCCCTCTATAGATTTGTAAAATTAATGGGATTGTCATACATGCCAATGGTATGGGCTAGAGGCGCCTGTCAGTCAAGGAGATAATTCGTACTCCCTTACTTCAGGGTAGATCATGACAGTTCAGGTGAGGTCATCTAAGGAAGGTCGCTCGGCTGTAGGGGTCTCGTACTATTAGCCCACCTCAGCCCATCCGCCTTCACTCACATATTGTCCCCCTGGCCTAATGGAATGGAAGGTGATCACTCTGGTCGGGTACTACCACCATATAAACACTGTCGCTGTAATTGTGTTCACTAAATACGCAGTCGAACGTCCCCAGTCCACGTCCGGGTGATGCCGCGCTCCCAAGTGGAAGGTATCGATTTAGGAACCATCGATGCTAAAGACTGTATCCTCGTACGCAAGCTACCGGGAGACACCTCCGGGAGCAGTGTCGGTACGCTTGTATAACATCCTGACAAACGCGTTAGTTGAACATTAGGCGTGGTTCGCAAGGTCGGCACTCGCTGAGACAGTGTAAAGTTTGGCGGCTCGTTACCATGAGGCCTTTTCTTCTTGGGAGGTGTTAACCCAGGGCGTGTGCGTATACGCCATAGGACTTACTAAGTTGTGGACACCCGCCCGCCTTTTTAGTTTTAATAATGCCCGGCACCTTTGCTTATGCGATTGCAACATCGCTGCAATAAGCTCGCTGGACGTATCAGGCCGGAGAGATGCTATCGCGAAAGGATTCTTCCCTCGCAGCGCGTTCGCATTCTCATTTCGATAGAGCTCGATTAAATCACGGAACGCTATGGAACAAGTGTGCGGGACCGAGAGCAAAACGCACGTGTTAGCACCTTGACCTAAGAATTGGGGATAAGGATAGCCGAATGAATGCACTTAGATGCGTTTCGCCGCCTGCTACCACATGAGCTGAGACAATTAAGCGCAGAGATCATTGGTGCTGTCAGTGCAATACCTATGTGGGCCGCCTTACACTAATTAGACATCCGCAGCCGCCCATTTGCGGCACGAAGGGAAATCCGTTAAACACGGGCCGTCCGAAGTCCACAAGCACAGGTCCGTGACCCGTGATGGTTCTGTTTTAAGCCATCTTTTGGCGTTCTGTCGATGAAATGCTGAGGTTAAGTGCGCGAAGTTGCTTTCCGACGAGACTGCTCCCTGCCGGCGGGTACGCGTACAGACCCTGCGGTCCGCGGGCGTGATCTAGATTACAATCGACTTCCACGGCTATCATCCGCTCGTTTGCCATGGAGTCGTGACAACCAGTCTAATTGGGCTATATCCCCTGCGCGAGTACTCCGCGGCCATAGGTATGCGTTACAGCGTTCCGGAGCAAAGCGTGCACTAGTATCTTCATCCATGAGGTAGACGATAGGGGTGGGATCGACTCCGATGCTAATGTCTAAAGTCCCCACGCATCTATGTCCCATAACACATGACCTACAGACCTTCTGTTGTTAAGATGGTGTTTGTCCGATGAATCGTAAAGACTAGCTGACTGTACGCAAAACTAGGTAGTTTGCTATCTGACCATGGGGTTTGTCTCTGTCGCTTTCGAGGGAATAATTAAAATCCGGGATGCGGGTTTCAGGCCCACGTAAGGCATCCGACTATCTACCAGCATACACGAAATTCTAATGAGTTCAGATGCCGTCTAAACAGCTGATAGTGACTGCCATCCTAGAGGACTCGCTCTCTTCTTACCCATGAGGTACTGCGTCGGAGTTTACTGACCACCCCCGATCCAGCTAGAGCGATGAAAATTAAGTTTTACGGACCATAGATGGGGTGTATACATTTACAGCAAACAATCGCCCTTGCTCCTAGAGTTACATACACGCCTCTACGACCTGCCAGCCAGATCTCGTTATCGCCCAAGGCAAAACTTACCGCAACGCGAGGCGCCTTTGGGACGGCTGCCTCATATAGCCGCCATACACATGACTACCCAGCGACGTTTGTAGAAGCAATGGGCGAAGAAGGACGATTCGAACACTATCAGGGGTGCTTCAGTTTACCTGGAAACGACTTTCTCTGCGATCCTATTCACGTCCTAAAGCATCTCCGCTAACTCGACGTTGAGATGAGCCATTGGGCTGGAACAACAGTCAGCCCCTAATGAGGCTACCTCGACCAGTTTTGGTTGCAAAAATCCGCCCCCGGCTCTCCTTACAATTTGCGGTCGCTTAGAGACATCATTATTCACGGTCGCCAGGATACTATCCGTACGAGACCTATGCGTAGATTTAAGACCCGGCATTCGTTTTTCCGGTGTATAATGATTCAGTTATTACCATCCACATCTAACATCAAGAAAACCAGCAGGCGTGATCATGCTTTAGGTGGGTCCAGAGGATGACGACAGGCTCTTGCTTATATCCGTTCACTACTGAGGTCCCGGGGACCCACATAAGGAGCATTGGGCAAAATACGATTGCAGAAGGCCGCAGCTGTGCTACCAATTCTTGCCTTCCGTGTTTCCCTATCACTAAGACACCGCAAAGTCCATCAGGTCGAGTCATCCCCAGCCGGCAAGCAGATTCAGGTAACTACACAACCTCACTGAGCAGCGACGGCTTATAAAAGTGCGTTTGTTAACTTAGGTCTTTAGCTATAACACGTGGCTGATCACACTCATTCATGTATCATCGGCGCTAATGCGGCAAGTGGGAAGACATCTAACCGAGGGTAAGAGTTCTATCTTAGATCCGGTATCGTCAATACTGACGCGAAGTTGCGGACCATTGGAGTGCGCGCCCTCTGGCTGTTTGGGGTATTTCATCTCTGAACATTTAAACATGTAAGAGGTTGAACGATCATGACTCCAACCACCTTCGCCCAATTCGAACAAGTTGACGGCTGTGTGAGACCCGCTCATAATACCAATAAAGAAGGTCACAAAGCTTAGTGCACGTTTGATGTGAGCCCAGCCCGCTAGAGGCCTGCTAAAACCTGCAGCTGACAGGGGCGCCAAGACGCGAATCTGTTGTATTACAAATCAAAGAAACCGACACATTTTAGACTACGAGCCAATTACGATATCGGGCCCCCTTCCCGCCGAAGAGTTTGTCAGTCACATAATGATCGTATGTCACCGATACCCCTGGAGGGTCCAAATATAAAGAACAGTCATTTGTAATCTGGGAAGTCACAACATTTATGACAGGAGATAAGGTTATACAGCCTTGTAAGACTCGGATGATAATATTCGCTCTATTGACTGGCAAGTATTGCACTATTTGCGAATTAAGAAACACCCGCGTCCCAGCTCGACATTCCCGAGTGTTCATTCCTGGTCCCATCTTGACCGGGTATGGACTGGGTCCCTCGATGAGCACCTGTTCGCTATCATGTGGGCCGATACATCACACACCCTGATCAGGGGAGTGCCGAATTTGCACCGTCCCTGTGGCATGAAGTCTGGTGCACCGGTTACAGGGATAGCCATTGAATTCAGGGCCTCAATGTAACCAGTAAGAGCAGTGGGAAAATGCTGATGAGTTCGGATGTGGTTGTAGTCGACAGAGTACCGCGCATACTGCTTCTTGAAACGTCCGCGAGGGGATATTCGGCTTGTCGGATTATGGAATGGGATCTCATAAATCTTGAACAACGAAACACTACATGCGTCCCGACCGTGCCAAGTCATCTATTTAGAGTGCGCTTAATATATCGTAAGTAAGTCTGCAACTGTTCCGGCCGTACTTCTTTGTGGTTCCTCACAAGTATGAACCTTGTGCTCTATTCCACCGGAAGCTGGTGACTGCAATCAGAAATCGACCTGTTCTCGTTGACTGCACCGGCTGACGCTTTCATACTCTTATACGGACGAATGAATTTCTAGTTAAAGCCGCGACTTTTTAGGAACAGAGGCACCGGTTGTATCTTCGCCCGGAAATATTGGCAGCTTTTGTTGCGTAGTTATGGCCATACTAATACCGCCTCATTAGTCTATATTGTTTGGGCACATATATCATCACGCGTACCCGCCCAGTACTAACCATCAATGGCCTCTACGAGACAGTAACATTTTAAGACCCTTAGGCGACTCAAGAACTTCTCAGCAGGGTTCTCGCGAGATCATAATCTATTGCGGTTTCGTTAGCCATAGCAGCATCTTGTATTGTTATCATGTCAGGTATGCGCTCTTGTGAGTCTGACGAGTGGTCTTGTTAGTCGTTTCCACCGCTCGATGCGAGTGAGTGCAGACCGCTTCATGTTCTTCGGTTGCTCGGAATGGAATGGGGCACGCAGGCGACAGCCTACCGTCCTGCCTGGCGAGGGAAGATTTCAAAGTCGCTACCCGATCTGGGTTGTTTCTTAGTCGGCATATTGGAGGCGACTCATAGAACGTTACTTCAAACATGGGATTTCATAGTTGTTTTAGAGCCGCAAGTCTTACCACACGATTGCATAACTTGATCGTATTGCGAAGTTTGAGTCCGGGAAAAACAAACCTCTAATGATAACACATGTCTGCCGGACCGCCTTGCAGTTATCACCGATCCGGTTCATAGGGTAGCCAGCTTCGTATGACCTTAGCCGATTACTGTAGAGGCAATTGCAAAGTCAAAGCGAAATTCAGGCGTACCTCAGACATAAACGGGAACCTCGTCAGCAAGATCGGTAGACCTAGGCTACTCACGCAACGCGGTATATGCCCGGTTACTACGCGACCACGTGATGTAACCTGCTGTGTTTTACCTGGATTGCCATCGCTGGCAGATAAGTATACTAGTGATCGTGTATTCAGCATTAGGTTATTTAGAGAGAACCATCCACGTCAGGTTATTGTTGTTAACATCGTGTCGGGCTCCATCAGAGATATCCGATCTACCCTGTCAAACAACGCGAACACGAGACAACTTTTTGCGGCGCCATTTGGCCGCCAGCCGCAGGCCCCCAACGTGGTCTTACCATGAAGGGGAAGCACTTGGACGTGAAAACTGAGGTCGATTTAAGTTTGACATACAGGACTCTACGATGACCGTCGGGTGACCAATAAGGATCTACATCTCTATTCTTCGTAAGCACTGATGGTAGTATTCCAGTAATGGGAAGCTCGCAGCCACTTTGATGCTCGTTTGATAAACCCATATCGACCAAGAGCCGGCGGAGTGGCGGTTTGCTTATCAAATTCATACAGCCTGAATTTGGTTATCAGATGCCTAGCCCCTGAAACTGCAGCTCAAGCCACTGACTACAGAACTGCCCGTTTCGCCGACATCAACCCAATCGAAAGCACGATGAATCTATCGGTAAACTCATCTGTGGATCCAAACAGCATCGTTGGCCAGTACGATTTTTGCATCCCCTAGGACAGGCGGGTCCCTAGTCCGCTTGGGGCCACAGCTTGAAGGATTAGAACAAGTCGTGAGGATAGTGTTCTGTACTTTACTATAAGTATTTCGAAACTATCCATCCGTTGAGTTGACTCACGTTCGCCATGGGTTGAAGATGGACCTTCAATGGTCCAGTGTGCGCAAACAACCAGTAAACGTATTATCGTATCGAGGCAAGCGACTCATCACGAGCGCCTCGTTGGGATCGCAGAAGGGACGTAGCTGGTCACCCCAGCTATTAGGCCTGCATTGACTGCCCGCGTCATAATTCGTGCGACAGTCTATCCCGGTACTCAGCTCTACGTTATGTCTACTAGATACTCGGCTCTTGAACACCTTCCGGGCAGGACCGGAATCCCTGTTCCAGTGCACGATAAGAAGAGTTTTCGCTTCACTGCAATAAGCCGTCGATTACACAGTGAATGTAAAAAGAATGCTGGCCATGAAAGCATTGTACAACCATGCCCAGGAGGGTCTCGGACTCTCTTTCGGACAACCGCACTGGCCTTTAGAGCTGGAGCGCGGGTAAATTTCGAGGGGGTCGACTTTTTCGGGTGATTCCATATAGGCGATGTGAGACACGGAACATAATCTGTCACGATGGATGTGCCCCATGACGACCGTTGACGTACGACAACTCGAATTCAAGGAGAGTAACGAAGCGTCCGATATAAAGTCCCAACGTCTTCCGAGATCAGACCCAACTAGAGGATAATATTGTGCCAATAAAGACAGGCAAGCACTGTGGGGTCGTCAGTTTTGAGCCTAGCGTATCGGCAGAAGCTCGCAAATAAAGTCACTGACGCACATCGGGTAACGTGGTGTCCCACTGGATTTAGCATTGCAAACGGCTCAGAGCGCGGGATATCGGTGTTCTCGACTCCGAATGTATTGAGTGCGCCGAGTCGCCTCGTTATTCCGGCTTGAGTCGCTCTCTTCTGGGATATGAGAGAATGCTTTCAGCCTCTGACATCCGCCGCGCATGAGAGAGAGATGGAGATAATAGGGTGTTGGCATTCGGGAAGGGCGCTCAATGCCTACCTCGTTCCCCTCATGGTTCCCGCCTTAACTTGAGGAAAGATGGCCAGTGTACTCGGACCCCCATGGAAGATTGGTTTCCATAGATTCCAGCAGACCTAAACGCTATCTGTTCTAGCACGTAGGTCGGAAAAATAACGGCCGTAATTGGTTTTTTTCCCAATATTACAGCCCTTCCAGAATTACATATCGTCACCAACTAGGAATACAAAATCGAGCCAGATTCCCAAGCGCTCCCATATCTTTATGGTGCATTGATATAGCCAAACCCTGGTAGAGAAAGGGTGGGCGTACATCGTCAACTCTTCTGAGTAAAGTCTCAATTGAAGTGTCTTACAAAACGATCCGATATCGACTAGCTGTCTCTGTTCCTTCGGTGCCCAATAGACATTGACAAGCTGTGAAATGTTGGTTGCACTAACTTTGGGAAGCTGCTACAAATGGCATAACGATTACGACCGACGGGCTCTATTCCCTTTTGCCCCATCCTACTCTGTTATCTCGCAAATCCCAGATGTGCGACCTCCTAAACAGACAGAGTGGTGTTCCCGCGATCTGCTAGAAGCAGAGTGGTCTGGGTACGACGTACCTTCCTCGCGGAAAGTTAACGGGAGGGTTACCCTCCTGATTAAGCTCCGCGCCCTCCATCACGACTCCGATGGCCCGTTCAAACGACCCACTCGATATAACAGGACTAAGCCACCGCGCAGGGACCGCTTGACCTATCGCCAGCCCGTTGCTGGGGGAGCCTTGCTTTGCAAAATTAAGCCCCGAACCGGACATTTGCGGTCATTGCAAGGGCAGATCTACTCGTAAAGTTTCCCAGTATCGAATAGCTACGAGTAAACGGAAGCATAAACGCATCAGTTATTCCGGGAAGCTCTCTTTAACGTTGCTATCTCGGTATTAAACTCATTTTTGCCTCCGTCACTTGACCCCACCGGAGACAAAAGGAAGCGCGCTCTAGGCGAGGTATCTACTCGTAACCGCATCCACCCGAGCGTGGGTATTTGGCCTTGGTAAGGAATCTATCGATCATCTGACACGCTACTCCGGCTCTAAATAGCTTCGTTACGGGGACTATTCACAAATCACTGGAACCCATCTTTGTAAAATTGGGGGGCTGGGGCCATACTCAGTAACTAGGCGGTTTCGTTATCCACAGTAAGCTAGCTTGCCCCTTCAGTACAAGATTCAGCACTCTATGTCTCATTGCGGGTGCGGTCCTGAATGACTGTATTTCTCCAAAAGTCCTCTGAAGCGTCATCATCGTCAAGCTCCTTATCCTCTCTAATTGTCAATATTCAGATGTTGCGTCCATCGGAGCTCGGTATGGCGTGATAATACCAGAAACGTGTTAAATGAATGCTGACGGAAGCCGTTCGACCATTCCCCGAGAGTGCATGGTCGTGTGGCGACAGATCCTTCATTTACGCTACACTTTTGGCGGTTAGACCTCACCTTCCAGGTGTGTCGTGCGCATCATTCGGCGCAAATGACAGGTTTTGCCGACTTGACGCCCTATCCGTGGCACCCCCCTACCTTCGTGAGCGTTGGCCCTGCGGCACTTCCCCAAACCCTGTACATCGTGGGAGATCAGAGACACTCATAAGTACTAGCGTTGGAAGAACCGGTGTTGGCGGGTGTCAGCTCTCTCTGTATCACATACTCTGAAGTCCTACCAAGAGGGACGCTGCCTACGCTACGCCCAGGTAAAGGCATTGGACTGCTTGTTTTGTTCGGCGTCGCCCATTCACTACATCGTACCCAACGGTCTAAATTGTTGGACCAATTTGTTCCACGGATGGGCGAGCTGCATCACCTCACAGCGGAACCCCTTCATAATTCGCGACCTTCCCGCAAGGTGAGGTATAAGGAAAAAACGGCATCCCGTGCAGTCGCGGACCGCCACTGGACAGGTTCTGAGTACTAGATGGGTGTGGCCGAGAAGATCCGGACTAAAAGTCGCCTCAATCATCCGTTACCAGTTTCTAAGTGTATACGTGAGCGACACATTAGCTCTGGGTTTCACCACCAGTCGAATGCGTCAATTCAAAATTGGCGTCCTCGAACACGCTTTACGAGCGATGCTCATCGCGACACTCCAGTCACTGTTAAAGGTGTTCCGTTAAGGCAAGAGCAGCTCCACATATAACGTCCATGACATGTTGCAAGCCTGCACCATACGTCCTTTTGGAGCCGTAACCTTTTCCGGAAAGAGGATTCAGGTCAGCATTTTAGGTCTCTATTAGTGACATTGCGGATTCGCTCCGTTAACTCAAGGCCATCATTTTGGGCACTCCTCGGAGGGACCTAATTTTACTCCTACTTGCGCGATATCGATTGACAAAAGGAATTGCGTCGTATTTTCCATTGATATAAAGTGTACTTACGGCCCTGACATATCCTCACGGACACGCCAACACCACCCCGCCGTTCACGTGCCCCCCCTCGGGCTACCAACTGCACAAGGGCACCACAGCTTGACATCCATCAGCATGTTTTTTCGACTATTCGGCCGGCACCAAGTTGACACCGCCGACTGACGCGTGGTCAGCCGATCAGAGGCACCAAAACGGGGTCGCATGCCTTAGACGAATAAGGGTGCCATCGATGTTGGGTATTATTACCGAAACATTCGGATTAATAGTTGAAATAAACCTCCTATTCCAGAGTACTTACCCTAGACCTCAAATAAGACCTGCGAGTGGATGGTCTTAACAATCGGGTGGTCGTGGTCCCGGTTTGGGATAGCGAAGGATAGGGCAAGAGGACGTCCAAGTCCAGTAAACTCCAAACAGCACGCTCACTCTAACAGGGCGGTGATAATGGGGTAGTTAGACGAGCACTCATCGAGCAGTACTTGCAACTGTCTTTCTCCAAGCGACGCTTGTCCCAATGGCATCCGTAGACGACGATGTGTCGGTCCGCCGTCAGGGGAATTATTCGTATGATGCCTCGAGTCGGTCTCGGGAACTTTTCTCGGTTTCCGGTTCCTAGGGTTGCATCCCTAGGTCCAATAATCATCTGTCGTGAAGGGGCGAGTCCTTCGGGGAGATGCTAATTTCTATTGGCCCCAACCAATTTTATGAAGTGTCGGGCGGCGATGTAGTAAAATTTATTTCTATACCATGAAGAGTGCTCAAAGACTGATCCAGGTTCTGTCAAGCTTTTTCTACTATCTATGAGACCCTAGCCCACTATGCACTGGATACGATAACGATGCTAAGGACTACGATGATGCGTGCGGGTATTTACGCTTTGTTGGTTACCATAACACCCACAACGGATCTCTTATGGTTCTTTGATACTTTAAGATCCTTACAATATATCAGACATGTCTACAAGCCCATTCGGTGAATTCTTTTCTCTCTGAAGAGGGTTTTGGCGTTCAACCGGGTATGCTGAAAAGCGACTAAAGTTAGCGCGAGAAACATTATAACACAAGCTCGCTGTCTTAGCAGGTCGGGCTATGCCCAGGAGGGGAACGATGATGGACACGTGTACTTGTGCGACCGGTCATGGACATATCTCTCCGTTGGAGCGTCCGTTCCCAAATGGAGAGAGACTGTGACAGTTATCTACAACTGCCGGTAGCCGTGCCCACTCCTACGGTACCGCTAGTCACAGGGATAGCAGGAAGTTAGTCCCAGTTAGCCATCACGCGGAAGTTATTGACCGTCTGAGTTATTGTTCCCATTATGAGCCTAGCTGAGATGAGTCTCAGCGCGGCTCCGCCTGTTGATTAAAATGTTTCCAGATTAGGTACTTCCATGAACTGATTTGCTCATACATTGACGGCGGGCGAGATGACTACGCTTGCCGACTACGTGGGCTCGGCTCACAAGCTGCGCGGAGTGATCGAAATCAAGTCAGTTGCACATAGCCTCACCCAGCACCCTTGACCGGAGCAAAAGTGCTGAATGACTGCCCGCGCAACAGCTCATGTCTAACTATAGGTCCAAGGAGACAACTTGGAGAACGTTCCTGCGCAATGCTCCCAAGGTAGCCATGTGCCAGGTAAACGCCTGCTAATCTAGTTAAGGTTACACACTAGAGGGGTCCCATTATTGCTCACGTGGGCCACGTGCTACACTTCGCCCATAGCGTACGGTCTTTCACTAGTTCCGGGTACCCACATTACGTACGTTCGTTCACTACTCGCTCAGTAGCTAAGATCGGGCTCTGGGGAGTTCCAATAGAGCCAGGTCCGAGCCATCAATTGTCTGACATATTTTAACTCTAGAACTAAAGCAGCCCAGGTGGGAAGGCCACAAAGGAGCAGCCGGAGACTATCAGATAAATACATACGCACCACTAGTCGTCATAAATAAAGGAGTTGTCCCCATGCTACTTAGGATTCAACGGCTGGTAACGGGACGACAAATAGGATTACGGTTCTGTCTTAGTAAGGCTTATTCTATGGAATGGGGACGTTGGGCCTTCAAGAACGTAAGGGAATGTCAAGTCCGGCTTGGTTTTTTCCTGATAGGCGTGATACGCGAGCTTTTGAGTGTAATAGCGGGAGTGTCTGTTGTTAGATTACTTTTTCCGTAGTATCTCACTCAAACTAAATTAACACCAGTAGGTATTATACGCGGAATCTTCCGCTTTTGACGTAGAGCATCCCGTGTCCAAACCGAATTGTCCTTTTTGGATCGCATGACATAAGGTTAAGAATTTACCACCACTCGTAGGGAAAGACCAAAGCGGGACAGACAACTGCCAGCGGGGCATAGCCTACTTCCTGTTATATCAAGCTCCAGCTGACTCAGAACCAGAGTCAGTAACGCCTATCTCTGACCTTTGGGTACTCCCACGCGGTATCATTGGCGACCAGCTTGTGGAGGATCCATTTAGCCACTCAACTTGTTTCTAGTAGAATTGAATAGACACTGGAGAGATGGCCAGCGACTGATCTTGTCATACACTTGTAGGTACTGTACCTAAGGTGGTTCAATCCTGGCTACGGGTAACAGTTGGTGAGGTGGGCCCTTCCTTGCGTTTGATGGGGGCAGCCTCGTTGGGACCGACTACCTAACCAGGTATGGTTTCCTCGCAAAGCATGGGCCGCCAGTATCAACTTGAATTCCCGGATTACGTAGCAGATTACTCCTGTAGTTCTTACACGCCCTCCTCTAGAGAGGAGCCGCCACATAGGGTACGCTCGTCCTGGGGATATTCACTATACGACTGTGTACTCCCTGGCACTGCGCAATAACCGGAAATAGGAACATGATAGCAAATCACAGGCATTGACCCCAGTGAACAATACCAACCTCAGAAAATGGGGGAACACCCTGCACCTCCGTGCTGCCTATAATACCTCATATCGTCGGCTCTCCATATGAGGGATAAAGATTCTTGTGCTTCGAATTTCAGACAGTCGACCAGTAGAGCAGAATAATAATCGTCGACCTGGTCAGTAAGGGGGCCGGCTAACGTAGACGTTCCCTCACGACCGCTCAACGTGTCTAGACAAGCACACAGCATATTCCGTCCGGATCCACCAGTGTATATTGGTAAGTTGCTCCCAACTGGTCAGGATGATCCTCGAAATTATTTTGGATAAATAGATACAATGCCTATCCACCCAGGTAACACCACTGGTACGCTATTTAACGCCTTCTCCCGGGTCGCTTAACTAAGTATGCTACACCCACATGCTTCAAATATGGTCGTTTCACCCTGTCGGTAGACTCGTCAGACCTTGTCTCATACCCAGTGATTTCAACCGACCAGTGGTGATATAGTAGACCCTGGCGGTAACGATGTATCCTTATTGACTCACCTCAACCCCCTGTTCACACACATTACGCCCCGTCCGGGGCGAGTAGTGCTGCCAGGATTTTGGGGATACAAAAGGTCTCTTCCTTAGCGGTGTAGGGGCGGATTTACCTGTTTCTCAGGTTAGAGTCACATAAGCTCTGAGATAGATATGAGGGCGTCATAGGTTCGCACCGGACATACCTCGCATGTCCCCCTGGCGTAGCCACAAGGTGACTAGAGCCCACCCTGTCCGCGACCTTATGGCCCACATCTCGCTACTCACACCATTGATGTAATAGGGGAGTTATCCTTCGTTCAAGTCCGTTACCAGGTTCATCAAACAAGCTTTACGGATTGAAGCATCCCGGTAAAGACAGTAGCATGACTCCAAGGGCATTTTATAGCCTTAAAGGGCGTCCATGCGGGCCGGCAAGCCACTAAACCTTCATCTCGGACTGTTGGTCCTCTTTGCAAATTCATGAATGCTTTATGCTGGGAGACTAAGAACTTTTGAGGTTTCTATAGTTCAGCGGTGCGACGAAGTGGTCAGGCGCTGTAAATGAATGGAATACTCCTAGCGGGTTACCCCAGGCTTGAGGTTTTCCTAATAAACCCACAGCGTGGATCTCACCCAAGGCGCTAAGCCATAAATCAAGTCCCTAAATGTCCTTTTTAGAGCAAATGATCAGATCTCTGCGCGAAATTTGATCAATGTAGGACCGCAAAACCGCGAAGTCCCGCTGCAATCAAAAGGCGTTATACCGCCACCATTCCCGTGTGCAAATATATAGGCGACACCGCTGCAAAGCTCGGCTCATGCGATCATAACCCCACGCATAGCTTCCTCAATGTTATTTGCACTTCCCCCATCACACTGATATGCCCGGATGAACACCATTCGGGGTTTAATAGCCAGAAGATCCGCCTGCCTAAGATAGATTGTGGTTTCACCGAAGTAATGCCAAGCCAGTAGGTGACAAGACTGTTATCCATTCACGGGTGTAATATTTGGCGGTTCTCCTACAGGGTCGTTCCATGTGCAATGGGCCCTCTTACGACCCCGAGCAGCCTGAAGTCTGTCGAATTAATCTTATTCCTCAGCCCGCGGTCAGGAGGGCCGTAGGTCATACAATCAAGTGAACTCTGGCAGCGTGACGGCAGAAATGCGTAAGAACAGGGCTGTAACGATCCATGCCGGGTCAAGAGAAGGCAAACGGGGCTCTAACGTCCGATCTCGACGAAAATCGGAGGAACCGTCGCTAAATCGCTGTGCGCATTATTTACTCGGCTCTCTCTTGCCCATAAGTTTCTAGGTACGTACGCACCAATAGACAGGGGTATGTACTTTCGGGTAAGCACTGATCGTGGTGTTGTCAATCGGCTTCACTAGTGCTAGTGCTGAGAGTTCACTGTCCTTCTTCCGTGCTAGTTAATGAACCGCTTTCTATCCGGAGCGGTCTTCTTTCGCTCACTTGTAACATGCGCTAGTGGCACTACCGACAAGCAAAGCTAAGGTGCCTCCTCATCGACCGGAGGTCCCTCCGAGTTTAGACGAGCTTTGTTCACTCAAAACGAACACGCTGCGCATAGAGCAGGAATCAGTAAAGGGAACAACCTAACTGCAAACACGTGGCGGCTTGTCGTGTCTGACTACCGGGCAGTTCGGGTCCTAGGCGGTTAGTGAGCGGAACGCGTCGCCGGGCGTATCCGTAAGGATTGAAATAATTCTCTAAACGCCCCGCGTCGAATCTATGTCCCTTAGGCTGTGCCCGTCATTTCCGAAGCGCCCACAGGTAAGAAAAGATGGGTTTTGCAAGGCAAGGTTGCCGATTGGCGTTCGCAGCTGTTTAACAGCACATGCCGCGTGCTATACGGCAAGGAGAGCCTCTACTCATGACCGTCATCACACGCCATATGCCGTGAACCCCCCCGAGGAGTAAAGCGATGTTCTGCTGTACTTACTTCACAATTGTTAGCCGTGGAATTCGCATTCATTCCAACCGTTTCAATGATTCGAGCAGGCGAGGCTCCTGGGTGTTTCGTAGCAGGGCCCAACCACGAACATCTCCTTAAGCATCCACCCACGTGTAGTATGCACACCATAGATGGCATATGATTGTTCGAATGCTACCGTGATGCGCCTGTCTGACCAAATACCCTGAAGTTGCGGGCGCTTGTCCAAAATATGTAGGCGGGACACAGGGCCAACGTATTCCCTACGTCCGTGTACCTAGCTCAGGGCAAGTTTCTTCAGATTCCATTGGGACCCTGTAATAAGCAGCTTTTAAATTACGCTCCCTTCAACGAGACGGAAGCGATTCCGAAGCACCGAACCCTCAGAAATGGACATAGCTGGTGTTGTGGTGAAGCCTGAAATCCGACTCGGTACTATTTGTCATGGGGCTCCGGATATTTGTTGATCTTCGCTGCATTTGCGTCAAACTACGACACAAGTAGGATGGGCGTACCGCGAATTCATGACATGCGCCCCGACTATCATGAGCCAGAATGTAGAATCCAGGCAGTACCATTGGGAATGATTCCGTTGATTTGCAGACGGCGCATTCACTCTAAAGACACATATTGCAAGATTAACCTTCACTTTAACTCATGTCTCATACGGGTTGTACCAGCTGCTAACAACTTGACGTGGATGGCCGGGAAAAGACAGTAGTGGGTAAGAGGCATCTATCAGCGATACCACTTTGAATATGAATTATCCTATTAGAACCGTTCGCGTCGGCTTCTTAAAGTTAAAGGTCAAGAAGCGCCGGCCATCGTTAGGGCACATAGTGGCTATGAGTTGCGAACGTCATAAAACTCGTATTTAGCGAGGTCTCGGGACAGGATAGGGTTGCTGCGTAATTGTACGCGGCAGACAGTACAAACGTGCGCGCGGCGACTCCTATCTCTCCCGCTTAAGCTTTATATCAGCCTGCGCCGGGTGTGCGCGCGAAGCGAGTCTGAGTCCCGGTCGCTAGTGATAAGAAGGCACGTGCTCCCGAATTGCCCCCCTCTAAGGTGTGGTCCTGACGAGACTTTGGATCACGCCTCTGCACAACCAGGGGTTAGCAAGAAAAGCCCAACCTCCTTGACGGCCGTTCGCCCAATTGTAATGTCCGATATTAGGCGAGCTCAAAGTTATCGGGTGCTAAAGCTTCCACTTATCTTTAGAGGGCGCACAGTTGAGGTACGGGCCCGAGAATCGGTTCTGCCACGTAGACTCTTATGTGGTGTCGTATGTGGCGTAGTTCAACCGCGTCACGACGAATCGTCATAAAGGGTAAACTATCCCTAAGGGTTTTGGAATCTTGCGCAATAGTCGCCTTTGAACGGAAGAAGCCTTACCCCTCTGCGTTCACAGGGTAGCACAAGCTGCGACGAGAGTTACTGGTTGTTTGAGGGGTGCCCTAGTAGGACCTCCGCCGTATTATGTACTATCATCCGAGTGGGCCACCGCGCCCGCCTTAAACACATGCTACCAGTCTGTGCGAGTTGCAGGTGGATCGGCAAGGGGGGGTCCGCTACGCATGTAACCATAGGGGAGGGGTAGCAAAGGTGCGAGGACCACATGCCGGCGTAAAAACGAACTCTCACATGTCAGGCTTTGCATTCTGCGCCCCATAATCATCTAGGCTTTGCCCCACCGTAGCGAAACAGTTAATGCTTTGTCGCTCGTGGCTTAACTTCCTACGCGTTCTAGTTGCTACCCGAAGCGGCGTGTGGAGTCTGCGTTTTTAAGACCGGTGTAGTTCGCATGCAGACGTGAGACCCGAGTTGTGCTTGTGCCTTGTGGTACAACTCCACATATAGTCGCAGTGCGCACGCAAGGCGCACTTCGTCGCTGGCCGGGTCGGGTCGTACGTGCGTTACGAAGCAAAGAGTTGTTTATTAGAACGCTGTGATCCGCACGTAAGACCCGTTACTAGCTGCTCCTCTGTTCTTGCAAGGAGTGGTCAGCACGTATACCAGAACAATATCCTGTTAGAACTGTTAGACATACGACACTTCTCCACCTGGGATACGTAGGAAGGTGCCCCCTCACAACTGATGTCTTCCGCATCGCAAGACAACGTTGCAAAATATTACCCAGCGCCGCGCGTAGTGTGCACGTGCTGGTCCCTCGCAGTACCGACGGTAGATTTAACTCCTAAGTCGTTAAAAAAATTGTGATTCTACGAGGAGAGGCCTACGGGTTCTTTCACCAATTCGATAACTTTCCGACCGTCATATTCCCAATGAATGGAATTGAACTGGACAACATATTACTGACATAGAATCATGCGAGTGATCAAGAGTTCAGGAGTAACAGGTGATAACCTCGGTCGTGGGCCCGCGATTAAACAGACCTTAATGCACTGGATCAACGTTATAACTTCTCTGTAATTGGACATATCTTGTATCCTACCCAGACACTGAGGCACGCGGCTGGCAAGCCCCCAGGACAAGTTCATGCTGCGATGGGCTTTATTCGGACTGCCGGGCCTGACCAAGGCCGATCTATGAGTAGGGCGCGGTAAGAGCGAGCCCCGTTGTCCCAGCCGTGCTGAGGGCCATCTGCCTGGTAAGATACACAAGAAATACGCCTAAATGTTCGAAGAAGGCCTTAGATGATGAAACGTTCTAAACATGCGCGCTAACAGGCCACACTGTATGACATTGCCAGTCTCAATGGGGGATACACTTGAATTAGCCAATGTCTTGCCTCGCCTGACACCACTCGACTTCGCTGCACGGAGCAGCGCTTTTCCTTCAGTAAGCCTATAAGGGGATCTCTCTAGTCACGAACTGCGGTTTAACCCGAGAAGACGTTCCTAGTGAGAGCGCGAGCTCCGAGTACGTTCGGCTAGACTCCGTGAATGGGAGACTTAGGAACTAAGCAGCGCGGGGTTTCGTTTATTGGTACTTGTGCTTGAGCGGACGGGAGCACTTCCTGAGGCACATGCCGGGCGGGGTCGCAGGTAGGCTTAGCAGAGACCAGTAGCTCGTCCGCCTTTCCTCCCGAGCGTGAAAGCGGTAGCCATACACGGGGCTAATAGGGAGCGCACCATGCCCACAGTAGGCCAGCCCGGGCCTCACTCCCCCCATTTTCAGGCTACCTGCAGAGCCATTCGGGTTCCGTGGCGTTTCAGAGAGACCTGACTATCGGTTTGTGTCAGCCGATAGTCTTGCGATGTAACACACGAAGGGATAAAAAAGCGGCCGCAGTGTAGTACCAGAGGTATTTAAACGTTAGACCGAAATTGAGTTTTCGAGCCTATCGAATAATTTCGCTAGGGCTAGGTGATCCATTGGTTGAATTTGCACGCTTGCAAATACAGGCAGTGTGTCATCCAGCTCGCCATAAATGTTCAGGCGACTGACAAGAATTCGAAACTCACACGCACTAGTATTAAGCTTGGGTCACCCTGAGGCACGGGCGATTGTTCCGGGATTGATATCGGACGCCGCTTTTTAAACGATGTACAATTATCATATTTAGCCCATAGGCTCGATCATTCAGCCTTATGCGAACCTCGAAGGCAGGCGGAGTTAGTCGCAGTCCTCAAGGTGCCTCGTAACAAATAATGGGCAGCGCCTGACAAGGGTTGATGTACACTCTCACAACACTCTTAATTCAAAGGAGCCCGCTTATGGATAAAACTAATCCCAGCATTATCTCTCTAGGCTTTTTTTGGGAAGCTTAATCTCACACCTTAATTCCTCGTTCGCGGCCCCGTTGACAAACCTCGACGCCCAGCCTTATAGGAACATTAGATACTCGAAATATGGCAGCGAGAAAGTCCGAAGTGGCTACAAAATGACAATTGTCTACATCGGGAGTATTGCCTCGGTCTTTGGTTGATTGGAACGGGGTTGCATAAAGTACGCGTACATATCGTTGCCGGATAGATAATCTCAGTATTATTCTATTTCATGTGTGTGTAACGGCTACTCCGAAGTCCTGTCAATCAAGACGGGGGCAAGCACAACAGTTCACTCACGGATAGCAGATTATTTACGGCTGAGTTCAATATCGGCAGGAGGAATTAATTTGAACGAAAATACACGCCCCCGGGCTACTGTTTAGCAAGACTATCATACGCAAATACTATGCCATTGCTCGGTGGAATTTCGTTTCCGGACCATGATAAACCGTGTTGTTATTCCAAAAGCGAAAATTTTGATTTAGATCGGACCCTAGCATCCAATGCAGGATCTAAAATAATAATGCGGATAAAATGATAAATTCCCTGCGATCGACGGACGCTAAGTATTGAAGAGCATATAAGAATTGAACGGGTGGCTCCTTCGGTTATGTGGCACTGTTTGCTTGCCTGGCAGAGTATATCAACAGTGATCAACGCGGGAAACTCGGCCGCGGTCCGATGCTGTCTGCTTGGTTACCTCCGGTTTACCATCTGGTTCTACGTCCACTTCGTGCATTTTTGTTGGGTAGGCGCACCTGATGAATTGAGCTGCCCCCGATTTCGCACGTCTGACATCCGAATTTTTTGTCTCAACTTGTCAATTCCGGATCGTCCTAGCTCAGAACCCACGGATCAGCTCGGATAATTTGTTTGGTTGTTTTTACACGTTTATCATACGAGCACAATGGATGGGGCTCATACCCCGGCCCTGCCGGCGTGTGACGAGTGGAGATATTCCTTCTCTAGCTGTTCCTTGTGTAGGAGCACGCTTGGTCCTAACCGTAGCCACTTCGCGATATTGAATGGTTATGTTGCAGCTACAACCAGAACTGGTTGAGGGAGCCCCGAGCCTCGATCGTCTTCACGTCCATACGCATTCGCCACCCTAGCTGGGCTTAGACGTTAAACTGCGACCGGGTAATTACCTAATTCAGTCAAGCGTCCCGTTCCACATTAATATTCCAGATTTGCTTAATGGCCCAGTTAAATCTATCATTACGTAATAGCTGTTACTCCCTAAAGCGCCAAACTTTTGACCCCTTGTTACTTACAAATAAACGGGTTGCGTCTTTCTTTCCACGGACCTCCATGCTCGAATATTGTCTCTTTCCGTATTGTACTGTACAACTCGGTGACAGTTCGTAACTACCTTCAATAGCAACCAACCCCTGTTACACCCGTCGGGCTACTAGTTTCTCTTTACAGCCAGCGTCTGCAGGTAGCTCAGCCCTCAGATTCAGACACAATATGAGGCTCAACTTTGCACTGAGTCCGTGGCCGGAGGGCTCTGGCTAACGGTTACGTTAGCATGAAGTACTGGCTTCATAGAGCCGGGCCTAGTCACACTGGTTGGACACTACCCGGATAGAACGCAAGTTATAAGATATAGGGCAGGTTCTGGGGTGTGCCTGGATATTTTTTGTCCCAGGTTCCTTGCGGCATTGCGTTCAAGGTCTCTCTTACCCAGTCGTCATATACAAGATAATACTATCGACAATCTTGACAACGTCTGTTGAGAGCTCGCGTCATAGGGACGGCAGCGCTAGGGAGGTATGCCCAACCGGGAATGTGGGGTTCTCCACACCGTATGTCCGATGGGCACAACTAGACCGTGTCATTATAAGAAGCTACAACCGAGATGCCGCACCTCTTTAATGTTGATCCTGTATTGTGAACTATCACTCAGCTAATTCGGGGCCATAGGATATAGGCTTCTAAGTCGACTTTTCCGATGAAAGATCACTATCCAGCGTGTCAAGGGTAAATGACATCAGGACGCTGACAATTTGGCTGAATCCTTGGCGACGCGGCAAGAATAAAGGCATAGCACGGGCGTTTGAGGGGACGCTGATTGGCTCGGGTCCAGGTCTGACCTCCACGGAGTCCGGATTCGAACTCGGTCAGTCACACGGGAGGCTTAGGAGCCTTCGAACGGACGATAATATCCCGTTACTCGCCACTGTGCCTGCCTATAATGGAAAAGACAACTTTTTGGAAGGAGCTCGCATTGTCCGCGGCCGAGCGATTTCATGTGGCTTTGTGAAAGAACTCGAGTTGGACATAATGTCTGTATATGTATCGCCGACGCGACATATCCTGTACGTGTTGTCGATGATATGAAATTGACCTACTTACATGATACCAAAAGGAGGCGGCCCCCGGAAGGTTGGCCCGAAACACGAGCTCCTCGCAAATGATGTCATGACGATGGCAGAAGCCGAGCTCACGTCTCATTCGGTCGCAAATCCTTGATTCGTGCCGTAAGGAACTTGGGAGGGTAATAGCAGGTGCCACGTTCTCCTATTGTCGGACGCAGTGCTTATGTAACTGATTCCCTGAAACGTAAGCTATTTCGTCCGGAGATAGAACATTATGTCCACAAGGCAAGATATGTTTCCTATGAGAAGAAAACGACGCTTAATGACTTGGTGTTCTTTCTCCAGGCAAGATACGCGAGCGCCTACGGAACAAATGACGTCGTCTACGACGTCCAGATCCCAGCTTTTCGTTCGCTGCGGCCCCCAACTTTGCCAGTAGTGCCGATTGTGCGTTGCGGCAGGGGTCCTTCATACTAGTGCTTCATGCATTTGCCAGGTACCATGGATCTGCACTACTATCAACCGGGGACCGCGCCATCGCTTATGGGGTAGATGATCGCGCCACATCGTTAAGCGCGGATTATCGGAAGCAATCGTCCCACGTATCCTAGGTATAAGATATAAGTTGCAACCGCCACTAATCCCTCACACTTTCCACGGTGGAATCAGATGTCAAGCACTACAAACTTGGTCCACAGATGGGCAAATATATGTGCTCATCTCATAAAAGGTGTGACCGCTCGTTCCGGAACCTCAACTTTTGCTCGTAGCGGGTATTCCTGACGCGATTCACCAATCGGGGCCAACGGCTGACTTAGACCCGGCAAATAACACAGTCCAGCGTAGCTTGCGCATTTACGGCTTTTTGAGCTGGCGTTCCCGCCAGATTTGCACAATAACATCGATGAACCTGTGCTGCGGCTAAATGATAACGGAATGGACAGTTCGCAGTGCTTCTGATTGAGTTCGTGACCAAAGTCATCCGTAGGCAGGGCACTCTATACCTCACGTATGTAGCCTGTGTATCCTTGCCCAAAGGCGCGCGCAGCTCGAGGAGGCGGGATTGACCGGGACACATGTATTCGCCTCCGAGCGAACGCAGTAAATATTCATACGCAACGAAAGAGCTTCTTACGGTATTAACAATTTCATCCGGGGGTTATCGAGGATCCGCGCCACGGGTCTGCGCGAGACTCACGTGGCGGCGGATGAACCCGGCAACAGTCGGTGCCCCTGCTCAGCAGAGCGTTATTGCGAAGTCCATGAAAACCTTATTCACTAACCCGGAACAGCCCCTTTAATACCAAGTGTGAGTAGAATATTCACGCATGGGCAGGGTGTGGCGAAGAGGCGGCCACACATCGACCGGAAATCTCTGTCCTGCGTTCCATACCCCGACGAATTTCATTTCCCCACGGACTAACTTTCAGGGGGAATAAGCGAGGTACCCCTGGCAGAAAAGGCGCAATGTCTGATGAAATTTCTCGTGATGCTCGTGTGGACGATGGCAAAGCTCATGGAATTAGCTAGCAGCAGTGAAGTAAAAGCCGCTTCGGCGGCGACGGAGTGTATCACATCGGGTCGGATGTGGTCGCGGAGTGACGAGATCGAGGATGTGAGAGATAAGGCCCGTAGATCGGCAGGTGTGTGCCCTACGGCTCACTCGTGGTCAGCCAACTGAACTCGTGACCCTCGTTATGGATCTTAAGCTCTAGTAGGACAGCCCAACTACCACGTCTTAGAAGCCAACGATAAGCCCATAGGGCAATGTTTTTAAAGGAGCCCCCGTTCGTTTCGGCCACAATTAAGAATTGAGTTGATCATGAGGACTATGTGATTTAAAAAGTACACGAAAGGCGCTCAACGGAGTGTACTAGGCATTAATCATCCGAGTACATGCTATAGCTTGTCCAACACTGTGCGATGCGGCGAGCGCGGGTCTGAAACGCACCCGATATTGGTTATGTGTTGGGGTGCCCATCGCGCTGTGTCCCCGGTGGGAAAGTGATGTGCCATCATACAAACGATCGTAAATCTGCTGATAAGGACAGACGGAAGGCTAAAATGGAAAGATTGAGAATTGGGCGACTTTCTTTATTCTCAGAAGCAGGAATAGTCATCCGTAGTGCCGTCAGTTAGTAACAAATAGTTGCACGCTGCGGGGAAATCCCCCCACTCCCGGAGTACCCAGCAAGTTAGGAGGGTGAATCCCGGTTGGGCTCAGCGGACACATGGTGCCGACCAGTATTTCCGCATTTTACGGGACCCATACAACGCGTAACGCTTGACACTGGAAACAATAATAGATGTGTCATGAACTTCTAAAGGTCAGTTCTGTCGTCGATCAGTGCTCTCCGCGATACCCGAATGCGATTCTAAGAGTGCAGCTTTCCCTAATTTGCTACGCGACGTATAAATTGGCCTAGATTGATGGGTGGCGTAATGAAAAGTTATGCTGTTGGTTCGTATCCTGTGTATTTCGGTTCTTCAATTCGCACAGTGATTAACGGCCCATGACTGATGGACGTGGGCGTGTAGTATGGGTATACCCCCCTCAATCACCCCGAGTGCACCTTCGTGCGAGAAGCACATCGCCTACATGATTGGGTACCCCCTAGCTAATGACACCTCCGGCCGGTGCGGCGGAGTCGTAGAATGGGCCAATGATTCATCCCCTTGTTTCGTCAGTTCAGGTCCTGTGATGCACCGTACCTGCCTTATCATTCTCGAAGCCTGTTTAAGTTTCGTTTGCGAATTCTGCGGCCTGCTCTGATCCGGGGAGACCTTCGAACATGTGGTACCGAGACTGAGGTGAGTAGTTCAACCATTTAACTGGAACAGCTAAATGTCGCTTTCGCCCCTTACTTCTTGTATCTTTCGTGGCGTTACCATGAGGAGGGCATTTCTGACTGTCGCTTGGATGGAGGAGTAGAATAACCAGTACCCTATTCTGGCCCTGTCAGCGGCACCGGAAACCGGGCCGCACGTGTGTTCGCAGTCATTTGTTGACGAAGCATGCGTCCAGTGAAACGTATCAGGCATAACTTGCAGGGTAGGAAAATAGGCACTCGTAGCCTAGGTGCAAGGCGTTTTATGGCGCTAGAACTTAGAAACGAAAGATCCGGAGCTGTCCGATAACTAGTTTAAAGAATCACCATCGGGGGATTGCCAAACGATACTACCATTCCTTACACCAGTGAGGGGGCGCTTAGTGGGCATGGAGTTGACGCGGGATGCGCGGGCCAACAGATTCCAAAAAGTGACGCTATTTAAAGAGGTGGGCTATGGAATCGGCATGCTTACAGCTGCTCTTCCTCCTGTAGTAAGTATATGCGACCGATGGAGGTCAAAAGGTCTTGATTCGTCGGTGGCCGATGTTATGCGGTGAGATACCTCCCAACGGCGTTGATAAAGGAGGAGGCTTACCATTACGCCCATGTTCGAGCCCCCAGCCAGACATCGGTACCAAGAAGGGTAGTTGGATACACCCCGTTGCCACCAACGAGTGTCTTGTGATTGGCCGATTTCACCAAGGGCAGATCGACCTGGCGTGGAATTCCCTTATGCAACAGAGTCGACAGTTTGGGGTGTAACAATTGTGCGTAGGCCCAGCCGTCGAGTGGTCCAGGGCTGGTACTATACAGCTAGCCGTACAGAATACTCGAACATTGATCACCATGTGACACATCCGAATAAAGGCTAGCTACTTCCGCACAAGCAGATATATTGCCCCGAGTGGATTCCCTGGGGTCTCTGAGGTATGGGGATAACATACTTTTTAGGACTACAGATAAAAGTCTTACATGGAAACCAGCTACGCGTGGTAAACGGATAACGCCACCGGATGTTAATTGGCCTCGCGAGAAGTTTCATATGCACTTAGGGGTCTTAAGCCGTAGCGCTCGGTTTATGCGGCATTGCGAAGTCTGACGAGGCCATTCGACAAGTCCAACAACTTATCACACTTGGTTTGTGCTGGGCTGTGAAGTCTGCAATTGCAGGTAACTTAGCACTCCGTGATCTACACCCAACCGGCCGTACCTCTTGGGTAAAGAGACTGACCCGGGTGTGATATCTGTGGTAGCCAGGTGTTCATTCAAATAAAAATTGTCCTAGCATTCCGACTCTAATTTTCAAACCGTTGCAAAATTCATCGTTCTAAAAGCAATAGCTTGAGAGGTCCTTTTTTACGGGTCACTGCATCAATATTCTTTCCTCTACCACTCAGTTGATCTTAGTCACGGGTATAAAATATCCCTACTGTACTGTTTGCCGGGCGCGACGGTATATTACCCGTGGGGCGGCGCCATCCGATAGACTCGTATATATCAATCACTTCCGCGGAAATTTTCAGCGTGAGCCAATCGATTGACACAGAGTCCGGCACCGGGGTGACGCATTGAGGTCCATGACACTCGAAACTTGGGCTACGACAGGCGCGGGACGGCCGGCTCGTTACTGAACTGTCAATGGGGATCGCGTGCTTACGGTGCGCGAAGGATTTATTTGAACGAAGGCATCTTCTTAATTGTCTTCATTAAAATGGCCTGGTATATAGTTCGCTAGGCGTTTCTACAGTACGGGTAACTTTCTCTCAAGCAGGAACCGCAAACGTCGATGCTGCAGTGGCATTACGGGGTGATCTTAACATCAAGGAATATCTCCGGTGATTCGACACGTCTCCCCACTTAGCGCGTGACCTCTGACAGGTACCGACTGTAAAAGATCTACGTGTTATATTCAACATTATCCAGCAAGTCGTGGAGTGCGTACATGTTATTGTTTGTGTACTAGAACACTACTATGACGGGTGGAGCCATCATGGTTGACACGGAAGGATAAGGATTGCGCACCCATCAGGAACATGTACTAGACACTGCGCGTTACCACCATAAGCCAGTGCCAAGGATATTGGAACGCTAGGCTTACAGTAAGGCCACAAAGATGAGACTCCTAGATCGTCTGCCGTAATATAACAACTGTACTGCTACAACGACCGATATGCGCATGGCATGGATGCGTAGTTTTCAGGGCATTCGGTATACCGGAGCTGTGCCGAAATCACCGTTTCGGCCACGACGCTCACACGATGGTCTGTGAGACAGGGGGGCTCGCAATCTTCCCCATGAACATGGCGTGATTCAAGAGGAAGCGGTGGCGTGTTCGTAGGCGGGGCGCTTTTCATTTCACGAGAGTAAGACAATAGCAAAGTGACGGCCACGATAAGGGAACTAGAGAAACGAAATTATATTACACGTGCAGTCCGGATGGCCTTGCTGATGTAGCTACATGTCCCACTATTCGCGTTGCTACAGGGGGTCTAGGCGTCTGTCGGAGATTCTATTCAGAACATATGTACAACAATCGGCTAGGACCCACTGGCTAAACGCCTGTGGCAGAGTCTCGCTTTCTGTCAAGTCTACACTAGTAATAATGGTCGCGACTGTGTGCTTAAGCGATCCCGGGCGTATCCGATATGAGAGGTAAAGGTATATTGCTCGTCCCGCCCCCATCTAGGTGCGCGTTTTTCTAGATGATTCAGACCCTCTAAGCACCGACGATACTAGTACAAGAACTCTCCATGGTACCCTCATGCAGCTGTGACGTACCGTGTAAGTATCACTGTATAACTACGATTGGGTAATGCTCGTGTACCTGGTCTATAGTTTACGTATGGCACGTGCCAACCGCGCACCTTTTAGGATTCGAAAAGGCTGCGATCGCGGATGTGCTGGCTCGCTTCACAAAGAATAGGGCGCCGTATTAGCTCGCGGCCGGGTTGCGTTCCCGCTAAGTTACTCTATGCACGCTGGTATAAACTCTAGAGATATAAAATCATGAGCCCAGGGCGGGTTGTAAATATCAGCAACGTAACAATTGTGTGCGTTCCTTGGTATCTGCGCAATCGCGATTCTGGGTTACCGCGAGAGCCCCAGGTTCCGGTTTTACAAGTACAGGGCACAAGAGAGATACAGATGAGTGCACGCAAGATGCATTATCGCCATAACTGAAATGGAAGTTCCTTCCGCTAAAGTTGTACCGCACCGAGAGAAACCATTACTCCAAGGACGCTACAACGGGCTCATCTTCCCGTCAGCGGGTATGCAGTATACTTTACGCGGCCGTCCAACATCCCAGTCTATACCTAACCTTAGACATCGTCTTACAACAGCCGGTATCCCTGTGACCGCCCTACGTACGTTGTGGGTGGAAATCAAAAGACTAAATCAATGGATTTCGATGTCGGAGTGACTTTACTCCATGTGAATAAGACCGGACGAACGCCAACTCGAATTGTACCCGGCTCTCCTTTATCGACAGATGCGTCAATACACAGCGAGATCTATGCCTCGAGCAAATCCGGACACTTGACGTCTGCGATCGTAGAAGGACGGTTTTGTTAATCGTACAAACTACCTCCAATATAGCCCCTCGTACTGTTGACAGCGATACGGTGCTATGGCACTAATCTTCACTGGCGTTTATGGGTATGACAGCTTGGATCATTTACCCCTGACCACTCTTACATACGGAAGACAAATTCCAACCAAGCGCTGGATCTTCGCCAGTGACACCAGAATAGTAACCGGGACCACACATTCCTCAGCTGAAGGAAAAGGTAGCAAGTCACTGGAAGGCCTGGGCACAGGAACGATTGCCAAAATTCTTAAACGAGGCACGAGTAGTGATCCTAAGGCACGGAAACAGCGCGTGGCCGATCTGTCGTGCACCTTGTGGTACTTTTCTGGACGAAGAGCAACGTGTATTAACTCTTAACGCTCTTCTGACATGGCTCACAACGCAACAACGTACCGTTTAAGACTCACGGACACCTAACGCTTCCAACCCCCAAGTATTCACGATGCTCCCTCCGTCGTATACCACTCGTTAACTTGATAGGCTTGCTGAAAACAGTGCTCAGGCCCGGTCGGTCGCCTGTGGTAGCTACCTTACTTTACAGCGAATCTAGCGATAAGTTACGTTCAAACAAGACTGACTTTAACGCCGACGGAGAGTTAACCAATGGACCTTCCAGCGGCGCTGACTGTTAGGTGTGCAACTCCCCATGCCAATTAAAACCAATGGGCCTTACAAAATATGATCTGAATGTCCACATTAGTCTGGGAAGAGTCATATTGTGTCCATAGACCAACTTATCAATAGCCCCAGATACTCCCTTGCGGTATGGAGCTAGCATAGTTGCTTTAGTTATTTGAGAACGTGAACTTCCTATTTGTTGTTTACAATTCTAATCGTCTCCTATGCGAACACATAGAGTCCTGACCTAATTCGTTACGTGGCTTGGAAGGTTGCACAGGTCTATAAAGCCGTAGACAGTGGTCCAGATCGTCTTTGCGTTAATTCGGGACAAATCCCTTCCAGTTAACGTTACCACACGGGAGCTCCTACACGAAAATGCTCTTGGGTGTCCTATAACCTGTACATCTACCCAGGCTCGTCGCACCCCCAGGGAAAGGCCACATCTGCGAGGGCTCTGGCGGACCGTGAGTCTTTATTCTTACTCCAACTCCCCCGAAGTAGGCACTGAAGGCCGTTCGTGTGACAGTTCGACCCAGCAGCTCCGCCGTAAAATGCTACAGAATGAGTGACCCCCCCAGTACGGACACAATAGATTGTCCCTCGTCCACCGATATGCGACGCAATTATGCTCGAGCACAGTTTGCATACGATGCCTACAGATGGGTACCACTTGGGCCGGGGCGACTTTCGCCGGGATTGCCGAATATACGTAATGCCGTCATCGGGCCATTTAAAACGGGGAGACTGGGTGGGGAACAGTGAACCCTGAGGCTAGGCGCAAACATTGAGGGGATCGGACCGTTCAAGCCACGAATCCCACGGCGAAGATATCTAGGAACATGTAATCTGACGGATCTCTTACGAAAATCAGAGAACTGGTGCATCAGTGTCATGCCTTTTTAGACATCATATACATGTCTTAGCACATGGCAATTGGGTGCACAACATCCTTGAGTCGAATTCCCTACCGGTTAAGGGGACGTACAGAACACAACATAGGAAGTCTAGTTCGATGACGATCGAAAGCTCGTGCAACATTTACATTTCACGACGGACTCATTAACGTTGCCCCGGCGTGATATACGTCTGCCACTCGGCCCGTCGTACTAAGGTAATCCACTTGAAAGAGCAAGGTCTCTTGCAGGTGACAACACGTGCCTTTTCCGGTACTCAGGTGAATATATCTCGTCCAATGGGCCTCGCCGCAACTATCACCCTCGTTATCGACGCTAGGACGGTTGGGGATTTCTGCATTGGCTCGTAACTACCATATAAACTTTGCAAACCGGATTCCTTGCGTAGGGACCTTCATTGATATGGAAAGCTGCTCATCGTAGGGTATTTGCGCCGCGCAGTTTAAATGTCTTAATGCTGCGCCTCTAACGCTGTCATAAAACGTTTTTGTGAATAATAGAGACTAACTTCCGCTATTTCAAGTGAGTCTTGCTGGTCAGAAACAG . PASS SVTYPE=INS GT 0/1 0/1 +20 900000 . C CTCCCGTTTATGAACTCAGCGCCGAACAGAAAAAATAGCCCCACTTTAAGTCCGCTTTAGCGACTCTAGGGTCCGAACGCGCTGTTTCGTACATGGCACGTCGGTAGGCAAGAACTCCCGTCCTCAGATGAAGATGCGTAATATCCTTACGTATTTTGGAACTCAGGCTGCCGAGCATCTTATTGGGAGACTCTTACCACTTTGCCCGTAAGCAGGGAAACGACATTTGATAAAGGATGGCAGGGAAGCTTTTATGCCCCTTTTCCTACTACAACGTCGAATGTTGACTTCCTGGTTAGCGTTGTGGCCTTGTACTGACCCTACTAGGGTTTCAGCTGCCTAGAGGACATTCGACCGACCCACGACCGCAGCTCGCGGTTCATACACGAGAAGCTACAATCCGCTTAAGTATTTGTTCTTTTCGTTCTAGGGCCCGCGGCACCAAGGAGGCTTCAGAAAGAGAATAATTACTCGATCGTCCCGTAAGTAGTGTATCGCTAACAGGGCCTGCGTCGTCCATACTAAGGCAAGGTGCTCCAGCAGGGCATAGGAATTGACCGGCGGGTAACATTGGAGACAACATGTGATTTGTTGCTTAATCTCGGTTAACCCGCCCCGCTGTAAAGGCGAGACGGCAATCATGAATTCTAGCACGCACCCCGCCCGTCTCTGTCTTCAAAATGTATTTTTGGCAACGAAGGATCAGCCTGTCCCGAATCGACACTGTGTTCCTATGGCGTAAAGAATTCTGTTCCTGAATCGCGGGCGCACCGTAATTCTTACTTTCACATCGAATTGTTAGATGCTGACGAGCAGAGCGCAGTGCGGCCGGGCGGAGATTGCAGGGCTGGCAGAGCCATTGGCCGTTGATGGTGTTTAGACGCTAAGCTAACCCTATGCCTCATGGATACTTGCTACACAACAGTGTCTGCGTAGGCTGAAATGGGGACGGCATGAGACCTCAGTGTCAACACAATTTGATGCACTGGGTTTTCTGCAACTACTTTACTACGGCTTTGTCCTTAACGCGTTAAGGGACTCCATCTCATCCGTATCATAAACTCCGTAGTGTATTGGGGCCAAATCTAGAATACGTACCGTCGACAATGCTCACGAGGGTTACTCAAAACTCGGCGGGGTGCCTCAATCCGCGTGCCGTGAAATGCCCGTATTCACGACGACTAAGCACTTAAGTCTCGGGAGCTCTGTTGCGTCTCGTCTAAGGGCAGTCTTGCTTCCTGTGTCTGCAAGTTCCTCTCTAGTGTTTAGGGTGCCTAATATACTCCACGTGTGTCTATGGACTCCATATGGTAAGTAATGGTGTTTGATAAACCCCTGGCCCTTTAGGTTCTACCTAGCCTAACTTCTTCCTTTGACTTTTACCCCCATTGATCCATGTTCGTCGAAGTGGCCGATTGAGGCTGCCGCATGGCCAAACCGCTAACCCGATCGAGAAGGTTGCAAGGGCGCATCCGCAAATAAACCATGGTTGCTAATTGGGGTGCAGGCGTAGAATTTGTCGGTTCAAAAGGCCCTCGACCTGCACAATGACTTGCGCTCGTAACTTATGATAGGGCCGGCATGGGATTATTCGAGGGACTCCTCACACTCAGAAGTTTACTCCCGGAGCACGACTTTACGAGGTGTGTTGCTTTATGATGGCATATAAAAAAGATGCACCAATCACCAAAACCCAACTATCCTTGACACGATCAGTGCGCGACCTACGACTACTCTAGTGGTACGACTATCGCGATGGAGGGGATATTCGTATATTTGAAGTTCATGTATTGATTCGGTTATGGCGTCTCCCTTAGTGTTTATGGACTTCATGCGTGCCCCTTATCCGCCCGCAGGCACCAATCACATTGTGGAGTTAGTTGGAGCGAAATTGGGTGGCTGTACGGTCAAACTAGAAGCATACCTTCACAAGGGCGTGGCGCTATGGGAAGTGGACCTGAGGGACACGATGGGTGAGATTCGGACACTCTGTCTACAAAATTAGGAGGTACCTACTGCTAGCGAGCTTCAAAATTCGGGAAGAGATCCTCGTACCACGTATTAATGAAGAGCCAGTGGAGCGAAGAAATTATCGCAAGACCGACCCTGTGCCGGCAGATGGACGTGTTAAACATGGTACATTGAGCAGTCCGACTCGTTGTATAGTTACCACGTGTGAGAAGACTTAGCTCGCAGCTAGTGGACAAGAACTCGGCCGAAGTTTCGTTCCTGTATTGCGCGTGTCCAGGATGTGAACAGTCCAACTTCATTATTTTATTCTGACTTGACACTGGACGTAAGTCAGCTGCTCAGAAACCGGAGTTCCCTGCCTTGGCCTGGGGGCCCCATTTGCGGATGAGCCCACAGGTCTCGTAGACTTAGGTGACGCCGGGATCTGCTGGCCTTATGTCCCTAGAAGCTTGGATGACCGGCCCACGGCAATGCGTAGTCAGGGAGGTATCCATGACGTGCGTGAGTCGGGCGAAGAGGGCCCCACATGCACCTAGAATAGCTATGTGTGTTTCTCGGGCGGAGCCCGACGTCGTCCCGCTCATATCCAAGTGCTTTTTCCGGGGGTTAAGCGGTGGCTTGGGCACAAACGGTCGCCTCCGCCCGCTTGGTCTCTCAGGTATTTCCGGGGGCACTCATAAACTACGAACGCGATCTCCGATAGCCTTCAGTTGTGGGGATGCGGCTAAATCCAAGCAATTGCGACGCTTTGGGTGTGGTGGGGGTTACTGATCCGGACTGCAAATTACTAACTCCGTCACCTATCAACACGTCTCCCTAATCTGTTGGAACCTCGCTCTATGACATCAGAATGCGAGCGCGGACATGGGACATGTCGGGACAATCTATTCTGCCTCTCCGGTACTGGGTACGATAAGCGCGACACAAGATTGTGCTCTTACTTCGCCGTGTTACCGGGTAAATCGCCGGGATGCTACTCTTATATGTGCCTTCTCACCTGAAGCCTTGCGACCTCGAATGATTTGGGTGTGAGTAAGCACCCGGGATCGAAGCTGGTAAGCACGTCACCATGTTAGAGATACTTGACCGACGATGCCCTTCTACGGCTCGGTTCACGGTGCCCAGCGGGATCCTCTTATCCCAGCCGGTGCCTAGCCGATAAAAGCTCACAAGCTTAAGGCTCTGTCAGGGGAGATGTGGGAGAGGCTCGATGAGAAGTCCTAACGACACCAGAACCCCAATTAGCACACATGGCTCTTCCGGGGACTTGGCTCTCGTAACTGCCTGCAATGTACTACGTCGCATGCTCATGTACCAGACATTATGTCCGTCCTTAACAGTCGTATTGGAGCAAGTTGTGAGTACAAACAGTACACAAGCTGTAGGTCACTCCCCCCACGTCTACCCTATATACTATAAGTCCTTGTAGCCAGGATGAGTAGGCCCCGTGTACCTTATTTGAATGCGCACCCGTGACTTCTGGTGGAGAACTTGGTCACGTCGGGTGGACCGTGTACGATACCCCACAGTGCCCCAGGAGGTATGGAACGATGCTGCCCTGAAAGGTGGAAGGCCGGAGTTTTTGTAGTTACAAACAGTACTCAGCGCTATCAGCAAGTGGACACGGAGAAGTAATTGAATGACCGCCTAGCAGTGCTCCGCCTCCGGGCGGCAGCCCGCGTGCCTCAGTCAGAGATCTCGAGCACGCACCCTTGCTGCTTCCGACTAATGGGAAGAAGTGGAGATGGCGACCCCCACGCGTTATAGTCCCAAGGTTGCTTCCAGGAGCTATACCCGAACCTTTAGGTCTAGACTTGTCGAGTTTGCGACCGTACTCGCTTTGTATGTCGACTTTTTTGAAAAGACAACCGTGGCCCGGTCACTGTGTCTCCAGTTTGGCGAGCCGTAGTCAGTGATCGCGCTGCTCGGGATCAATTATCTCCAACGGTCAGCAGATCTACGGAGTCGGTGGCCGGTATAATGCTGGAGGCCGGTGTATGCAGGAACCTAATAGTCCCCGAGTGTCGATCTGTACGGGAGTCACTAAGATAAGGCAGAACTGACTATCTCTCCACCGCTACGTAGTCCAGTGCCAAGGTGTGGTCATGGCCCACATAAATCAAGGATTTGTATGCTAGAATTACGCGATCGAGTGACACTCAGAGTGCACTGGCTAAGGACTCTAGCTTTGTAAAGACAGCATTACATCAACACTCGTTGCATTCCTAGACTGCGGTTCCTTCGGGATCTCCCCTTGGTACTTCCTATATTTCCTGAGATGTGGGCGCAAACAAATGCCAGATCCCGCCTGTAGGCATTCGGGACGGGTACTACGCGATGACCATATCGAGATTGAATCTTACGTATCTCCCTACAAGTGTGGCTTAAGGGGTTAGCACCGACAACTCATATAAAAACCAAGTAAAGAGAGTAAACACAGTGCGGAGTAGCCGTACTTGCGAAGCGCCATTTGGGCGCGACCTTCCGAATTTGCATCCGACGTCGGTCGTATAGCAAAGAGCGATTCTGAGCCTCCAGTCGCGGCCACGTCGCCGCTTGGCCAATGTATACCAGTTGTGAATAGGTCGCGGAACGCTAATGGAAGTAACCCCTCCTATTACCAACACGCCTCAATCGTACCACCGGTACCCACGGCATATAGAGACTATACGGCGTCGCGGCGGGCCTCCTCATGCTCGTATGGACTACACACCATGTCCTAATAACCTTGGTAACATTACGCCTTTGAGGGGTTCTTTATCTCCGATTTCGCGGTAGATAAGGCCACATGACATTTTCCGTTCGAGCGGACACGTGTCGCCTCAGTAGCCTATTGCCGTCGCCCAACCTACGCCACTGGCTCATGCCATGCCATCTCATACAATTAACTCCCGACGTTCGTACCAGGTGTACCAGGGGGTCCATACTAAGAGAGTGTGACCTCCAGATTCTAAAATACTATGTGAGGAAGTCATGATTTCCTCTAGTCATTGTGGCACCGCTCGTACCGTGAATCATATCAGATAAGAACGATCAGTTTGCGACTGTTATTCCGAGGGTACAGTCTTTAAGACACCATTCGGAAACGAAAAGGGACTAATGGATGCCGCGAAAAACCTAAAAAGGAAACAAGCTATCGATCTGTGGCGCCAAGGAGGGCGGGGCCCCGCATGACTCGTCAACTCCCATAGGCACCGCTCCGGGCCGGTAGCGACCGGAAGGCAATTGCTACCCTATCATATAAATGATCCTGGTCATTAGTTGTGCCCCGTATACTTGAGTCAAGTATTCCGTCGCAGAGACTACTGCTCATCCGAGACAACTTCTTCTCTAAGCGACCCGGGCGGACAAATTCACACGCAGATGGGAATTACACTAGGGGTATACTCACCCGGGCCTAAGGAAGGCACATGAGTGGGGCGGGCTGATTAGCAATTGTATCAAACTAGGGTCAGGCACACATAATGAAGGAGCAAATACATTGCACGGATATAGCCTAGTCGAGTTCGACGCGGAAGAGGTAGGCGAAATAAACTGTGAAAATGGGCAACACCTCACGAATGGTCATGAGTCAATGTAAAATCTTCGCGGCTTACTCGGCCTATTGCTATCGTGACTCCCAGGCCCTCAGTCCACCTCTCGTCAGATACTAGTTCGGGAGGCTCGAGATAATTGACCCTCCCTAATTCAAACTCAAACGAACTCACGTACGGGTAGGGCACCTAATTCGAGATGAAACATGCCTAAACGCCTCGAGAATATGTCTGTTTTGTACATAGTCTGTCGCTTATTCCACCACTTCAATCTGAAAATAGCGGACTAGTCCCGAGGGCCCCGATTTGACAGGTGGTTGAGAAGATCAAGTTGCACGCTAGCACCAGACCCTAACTCGCAACTGCTCTGCCTGATAAAAAACACATGAATCTGCGAACCATAACCTTCTTTGCCATTCTTTGTCTGCGGTTAGCGATGGGGGGTGTAAAACCACCTGCAGCGCGTCCCGATGATAAGCTATATGGGTTCACGTGCAATCCCAGAATCCTTTGGGGGGTGGATCAAATTGAAGCGAACGCAGCGTTGTATCGACGGTGAGCCCGCACATTTGAACTCGTTCCTCGGGTTCTTCGATGAATGTGGACTACGCTAGTTGACAATGCCTGCAAGTCTCCTCTCTCCCCCACGTGTAATATTGTACATAGTCAAGAAAGCTACATGCACGCCGACGTATCTTCTGTGCTTATGGATCGTTATAAAATTTTGTACTTACAGTGAAAATATGAAGGATGAAGCCTTAGAACTCGCTGCGTGAGAGAGAAACCCACCTATAACAAGACGCACGTGGCGCACATCCGTCCCCAGTGTTCAGCGACAGTTTGTCTAGCCAGTGAATCGGATCAGGCGGTCCTAGAGGTCTAGGCGACTTATGATCTTAGTCAGTAACCCCAGTAATTACCGTGATTACCATTTACAACGGTTAATTGGGTTGGTCTATGGTAACGCACAAATTACTCGTCATACCTGCTTAACATGCCTTCGGGAGTTAACGCTGTCGGGCGGGGTCAGCTTACATTACAGTAATCCGGCAAAAGACAAACCAATGCATCTCAAGAACCAACATAATAAAAAGCCTTATCAAATCTGGATCACAACTAAACGTATCACAGTAATATGTATCGCGAGTCTAGGAACTTGAGCACCCAATCATCATCCGTGGCGTCTCCGCGGGCTCTGAACGAGAAAACTGGGCACTCCCGGCTACTTTGAAATCAGGAAAAGGTCATCTGTTAAATGTCTGTTCACGATAATAGGCTATTCCACTTCAATACATGAATGACTTAGGATAGATATTCCCCTGGGCACGATGTTCTTATGGAGTGCGGGATTTAGTGGATATTCACGCTTGTATTCAGTCCCCTGTCCCATCACCTTTTTATTTGTCCTCCGCCCGGATTCGTTTCGTGCACGGCCAACGAGGAGCTGTTCATCAAATCTACCGACATTAATAAGTCTGGCCTATATGTCGTCCAACTAGGGACCCCTTTCAGAGTAGGTGGAGCTATCGTAGTCATCAAGTCACAAAATGAGTTCCTTTAAGGTGGCGATGTGTTGGGTGCAGACAGTATAGATAACACTCGGCATGGCTTTAGTCCCTCTATCTCGGATGCGCGCATCACAGATACCGCACAGGGTCCCACCTTACATGTTCGGTTGGGACTGAGTGGAAAAGTTGGACCCTAATGGTTGCTTCCGCGAGAACAGAGACTTGAAGCAGTCAGTCAGGGATTCAGTCCGTCAGATAGGGGTGGAAGTATGGCCGGCGGCCATTTGAAGTCGGCTAGCAGCAAATAAATTGCGTAAATATGTTGGTGTTTGGGACAAGGAGGCACGGATCCAGACGTTACTGAGTCCCCGAAAGCGTTACTCACGGATACACGCCATACGCTCTACTAAGAAGAACCATGCACGGACCATTCGATACAGTCTTTCAAACGCCAATGAACCAGGAGCCGGGGGGATGAAGGTGGGTTGGAGGCATCGGAGTGGTTGGGAACTGGTAAACGAGAAGGCCTAAGAGTACTCCCAACGCGGTGGGTAGTATGTAGGTTGGTTTAAGTCGCGTTATCTGGAGCCCGATACAGAAGACCATCAGCTAAGAGTGGTCGTAAGACAACAGATAATCCAGGCATACTAACACCGTTTTATTAACACCTAACCCGTGCGCGGGCAATGATCTGTGATTTCGGCGGAACCCTTTAGCAATCACTCGAATGCTCCCCTCAAATTTGAAAGGCATGACCTCCGTTGTACGCCCTGGATTTCTTAGGGATCGATTAAATTGGAGGCGAATCGTGTGTCTGATCTATTGGCCAATTTGATAAATCGGGACAGAAAACCCTGGGCAGCTGTATCCCGGCCAACTTGACTTTCACCTTTATGCTATCAGAAAAATCGGTGAAACTGAAAGTCTCTGAAGTTCTCTGCAGTCATGCGGGTACACGAATGTGAATATGAGCTGTCGCGAGTTAATAGGACAGGCAGAAGCGCAGGTTGCGTCCTAACAGGAATACTCTTAAAGTAGGTGCGAATCGAGCAACGTCATCGCGTCAAGCGCGACCGCTTCAGTTGGTTGGAGGCTGTCGGCAGGTTCATCTTGCCAAATCGAACTAGCAGTGGCTTCGTTACGGGCCAATACCACCTCGAGGAACCCGGGTAATGAGGTACAGCTTACACAGGCAACCTGACAGAATGGATGTTTGACCTTCTATGCTGTACGTGTTAGCCCAACACAATTAGCAAGATTGCACCGGCGCTAACAATGTTAATGAGGTGTACTAAAGAGGTCGTACAGACAGGTCATGGGGGTAGGCGTATTTTCGCGCAGAACACGGGTCTATCCCATGAACGTACAGGCAAAATATTCGTTCTAGGAGCTGTGGGTCGGTTCCGTGGAGAAAAGTCGCAAGGCTATGTAAGCATTCATGCCTAATCCTCGCAAAAAGTGTGTGGGATTAGAAGCGTGTCTGAGCAGATGTGGTGCGGGATCGAAATAAGTAGGTAACTACCACAGCACACTATTCCAAGCAATAGTTCGAAAAAGGAAGACAAACCGATTCGGTTAAACTTGTGGCGGTCCTTTATTGCGCTAGCGTGCACATACTTATAACCGTTCCTTGCTAGATGCCAATACACGATATTGGCACATCAGGTGCTTTCACCCGAGACAAACGGCCTCTGCTAGCAATCCCGGGTCGGTAAAAATAGAAGACGAGAGGACGGCGATCATATCGTGCGAATAGTATCAGGCTTCATATGGGCAGTTCGCCTCGAGGACTACCCTCGTCGAAAAGCTTTACCGGAAGATGCCAAACCCGGGCAGCGGCACCAGGCTGTTACCCGTACTCCTAATAGCTCGGCTAAAACACGGAGAATGAAATACCTGTACCAAACGCACGTTGAGCTTCATCCACCTCTGGCGTGTGTACTATCCTATAGCGGATTTCGCCGGAGTTGCCTTTTCTCCTTGAGTGTTGATGCTGCCTTCTAACAAGCGCCTTTGCACCCAACATCGACATTTAAACTTTATTATGGGGTTGGTCCTGCTCCGTGCAACTGTCCTCTCTGTCACCACTATATTAAACATAGTCTGACCTAATGCAAGTTAGTAAGGAACAAGAGCAGCCTCATAAAGACTTGGCGACGCGTTGAGACACATATTGGGTACTTTAGGGATAATAAGTGTGAGGTACGAGGTGCGCGGACATTATCTTGATGCCCTTCTTGGAAATGTCGTATTTCAGGCCCCTGGTGCGGAAGAACTTTGGCCGGGTTTACATAGTTTAGATAGTCCTAGGTACATCAAGACGCCAGTATGAGTCCGCGAGCCGGTATGAGTCATATACAAGCCAAAGGGCCGCCTCCAACTTCTGTATCCGTAATTTTCTCCATAGGGCTCTGACCAGTATTGACCCCAAAATGTGGGCTGCAGATCCAAAGAGTTAACGGTACTACCCGAGGGATCAGTCATTCACTACGGTGCGCCTTGGATGGGATCCTACCGTTGAATTCGTAGCCTCCTGCGCTCCGCTAACCCTGACAATATGTGCACTTCGCCTGGACGTATTGACACCTGAAACGAGCACTGAGCGTAAAGCTAGTTGTTATACGTCACTGCACCATGTGGCGGGTTATAGCATCCTCCCATTTAGGTAATGCGAATCTTCACAGACATGACGGGGCATGTGGACTTACCGGTTACTTCGGGAAAACTGGCAGACAAAGGTTGGTTATAACCTACCAGCAAGTCATAATCTGTTTCAGGAATTACGCAGTTCTGCCGCTCATCCTAAAAATCCACCGACCCTCGCACGTGCCGAGTTAATCTACGGAACGCATAAGAGAACGGAAGCCCAACTGGAAGTTGGACAATGCCATGAGCGCCCTCGGACCACCCTCAGAGAGGTAATTTAGGGGAGCTAGGTAATGATCACGCTTTTCAGTGGTCCTGTATCGTGCATAGGGAAACCACTCTGGATAGTGCTTCTAGCGAATCGTCTAAGTACCCCATCCTTATAGCCCTGCCAAAGTGCTGGTAGTAGCTATCCGGATCACCACGTTCGGGGGACGGGGCGTGGCTCGTCCGTATGCTGGCTTCGCCGTAGCGCAGTCCGAAAACTGACAGACATAGTGCATTAGCATTTAAACCACCTCGAATAAGATTTGGGCAGATAATAGCGCCATCGTGTGCACTTGTTGCTCGGTGCCACCTAACCCCGAAGCTCCTAAGGCGCGGGCCTATAATCGTTATCCCCTACGAAATGCAAGTGCGTCCTTGCTAGAATCATTTGACTCTCCAGGGCCGGGAGTGATAGACCTTTTCAGATGTGTACCCAACGATGGGTTCCTACTCACGTAGATACCAGTTCAACCGCATAACCGTGAATTTTGGTCCGTGTCGTGGACGCCCGGAATGATAAGCCTCAACAGATTGCCTGTTTAGCTGGTCGATTGTGCCGATCAAGTTGACGTGCTAGGCCGGCGCTAAGCGTAGAGGAGAAATCTCGCAGCTTCGATACACGCGAGAACTTGGGCGTCACTTACATAGTCGGAGGTGTCATGGTTGAGCCGGTATCTCCGATTGATCACTCGGGACCAAACTCTATCTTCCTTCTAGAATCATCACGCCGACTTGAACACTGTCGTCGTTTATCACTGATAACGCTTATCAGGTTACGTGGAATCGAAGGTTCAAGACGGTCATGGAGCTGTTTTCTATTATTTCACTGTTAGTTCTTGGATACTGGCGAAGGACGCGCCACTTAGACTGTGCAGTCCCCAATTGGCTCGAGATTCCATCGGCGCGTCTACCTGACTCAATGCGTTACAGTCTTGGCCTGGCGCTCCTACCCCTGCGGCCTATAACGAGGTGGCTGTCCCGCGTGCAACACTCGCGAGCAACATGCCAAGACTTAGGTATAATAGCTTAAAGGTGTTCGCTTCTTGGTAGATAATTCTGGATCCGCGTGCCCACCTCCCTGTGCTACGAAGTTCCGTGAACAATGTCTAGATGTATAGCAGTGTGCAAGCCACCAGGTTCTATGGTGAGCAGCAATACAAGCCGTAGGTGACGTTCGGAATGACCCGCAATTTGTCGCGCCCCAGAGTAAAGCGAAGGCTTGACACTCCCGACTAGTAATCCCATGTGTAGGCCCCAGCACTAAAACATCTCGTTCCTCCTCACTTCCTGTGCTCAAGCCGCCTGGGGTCGAGGCGTAAGTACGGTCTTGATTGGTTGATTTTTGGACAATATGATGTCTCTACCAGCAACGCCGCCACCGGTTATGTCAGTCTCTGAGTTATAGCTACAATCTCAAGAATGTCGTGCGGCTCCCGTGGATGGCAGACGAGTCAAGACCAATAACAGACGTGTGGCACCTCTGGTCGTATCGTCACCCCCAATTGATGAAAATGTGGCTAGAGTTCCGAGGAGGACTTGCAAAACGAGTATCATTGATCCAGCCCATTACTCCAGTGTCCAAGCCCGAAACTGTAAGAGGGCCATTGAAATAATACCGGCTAAGGAATGTCTCGGGCGTGCGGGAATCATAAGGATCCCTCAGTTGACGATTGGGCGCCTCTTTTGCGAGCGGCATCCGCTGCATCGAGGTAAATATGTGTTGGGGACACAAGCCGGATTGGCATTGCCGGAACTTATGTGCGGCAATTGCAAAAGTCGAGTACTAGAAGGATGATCAATTGCCGATGCGCCAATTGAAGATGATCGCCTAAATTGGCTTGTTCATCCTTCGCTCCTGTACGAAGAACTCTATCCAACAGTTGATGGTTGGCAGTAGTTCCGCACGAACAACAACGGGATGGAATTCACGGACATGTTGGTGCCTAAACTAGCGCCGGTTTACCGGACGTGTCCGTACTCATTCCCGCCGCGCCAGCCAGAAAGGGTCGATAATTGCAACCTCTCTCGCAGTATCCTTTGGTCGGCAGAACGCCATGGAGCGATCTCCTATCTCTCAAGGTCAGTTTAAGAATTATGAAGTACTTCTCGACGTGTTGAACTTCCGGTCTCGGCCGTTAGGCTCGCTCGATTGAAGTACAACAGAATTCAGTTTAACCTACTACTCGCCCCAGAGTACTTCCTATGAATGGCTGAACTCTGACACCGAGTAGACAAGTGGTGGATATACTCTTTACGGGAGTCACGTATATCGTACTATTATGTTTCAACGGTGCTTGCCATCCACCACAACACCGGTAAGATTATCAACGCTTACTCTCAATATTGCCCGCGAGGAGGTCTTATCCAAGGTGTAACAATAGTAGTCTGTAGCGTTGAGATTAGTCTTAGAAACGGTGAAGGGCGTTCTCGTGCGCTCGATACCGCTCCCCCCCAATCGTGTTCGGCATCACTAGGACATACAGCGGTCGCCAAAGCCTTTCACCGGTATCGCTTCTCGGGACTGATGCTGCAATACACGCGTAGTCGAAGCAAATTTATGGTGCCCAGCATCTGAAGCAACTCCATAACTTTTACCGTCGATAACAGGATTTGGTAGTCCGCTCGGTACTAATGCCGCAAAATGAAGCCCTATAATGAGATATCCTAAGGACGTAGGGCGCCATTGTTGGTTAATTCCCCCTACGGATTGACGGGCCGCGCCGTCGGGCTGGGGTTCGTATGAACCTAGCTCCACGCCAAGACCTGTCCCTTGTCATAGCCAACAGGACACCTTTCATTATGGCGCTACGCATATGCGACTGTTCCCACAGTACAATGATGTGCTTAACCATCGTCGCTCGGCGATAGGGTATCTTTTAACTATCTTAGACTGATAACGTGTGGGCCGATAGTATCTAAGAGCTGTGAGGCTTGTGGACCACTTAAGCTATCGACTCCCATTGGGGCAAGTGATTACCCGGGTGCTATCCACAAGACCGCACTTGTGTCCTTGCGTCGAATTAAGAAAGCTATAGGGACCAGCTGATATTAGGTGCTGAGGAGTGCTACCGGCCTGTTTCACATATATCAGAACGCGTGCCCTGAACTAAGACTCAGCCAATCAATACTGCGTTGTGGGTGAGGCAAGTATTCTGTCCGGGGATGCTGTGGGGGACAGTATTGATCTATCATACTAACCATAGTCGACATCTCAGGTTTTCGAGCGCTGACGGTACAGACAAATTTAGGGCGCTACGAGAACAGCATGTCGCTTGAACCGACTCAGGCGCCGTAATTAAAGGGAGTGTGCCATGAACTCGAACGCACTCCGTATCAACGCAGAAACCGCCTTACAACACTGAGCGGCGTAAGAATACTCACTCGATATTGATTACCGTAAGGCTATATTTGTATGGGAAGCAAACGAATGACATTTCCTGGATATACAACAGTTAGCTGAAGGCATATGTGATCTGCCAGATTCCAGAAGCTGATGGGGGATCAGGATGAACCTTGTCAAGGATTCGTATCTGCGCTATACAGGGAGAACTGTGCGATTGTTGAGGCTACGCCGCGTAGCCGAGCCGTTGGAATAAGCAGCCCCGTATGTGGACATTGGTAGGAGCATATTCAACGGGCCACTAAAGGTCGCAATTGCCTACATCAGATGAAAGGTTGTTACCGGGCTAATATCATATAGAGCCCTCTAATATCCACCTGTTGTATGAATACTGTCGCAGTTTCATCACGGTTGCCCCTAAAACACTGACAATTAGGTAGCGGTATCGTTTCTCATCTACTCAAGGCGTATCTTGGGTCGCAGGGGCACGCCGTGGTTGCTCGCCAGTTACTTACTGACGGTACCTCTCATTCTTTGCAATGCGGGTACTTGTGTCGTTGAAAGTAGTGGTACTCGCACCAACTCAATCTATCGCCGCTGCGAGACAGTCCCCGAAAGCCTCCGCAGGAGCAGCGCTACCTCATATCCTGCACGATTAGAATTAACTGCCTCTCTAGAAACGAGTCTTACTAGTAGTTGACCTTGATTCTACGGCCACTCGCATCGCGATGATTGAGAGAGTTCCCCCACTCACGAATTAGGAATCATGTTGTAACAGCGGTCCCACTTGAAGGTGAGTCTCCATACAACGAGTACATACTTGAGCAAGCAACTAGATTATCAAGAACACGCATTTGTCCTAGCCTGAACCACTTTTGGTCTCACATAAGACAGCGGGAGAAGCGATTCGGGCGACGAGGCTGTTAAGTCGCACGGGTTGCTATTCATATAACACCTCGCCGTCGTGTTAATGATGTTTATGAGCCCTGGCGGTATGCAGAGCTAATTGGTTTGCATGGGTGAGGTAACTTGATTCCGTGTTTGGTAACGAGCGGCGGTCTACACCTAGTCTCGGCCATTGGAGACTGTTCGCGGGGGTAAAAAATCAATTATACAGACACTCTAGCCTGATATTGCCCAATTTGAAAGAGTTCAACCTTTCGCAGTTTAGTGAAAACTGAGCGGTTTGTGAATATTACCGGCCTTATATATCAAATGGTCCGGTACCAAGCCTAGACATGTTCGGACTTTGTTCCGTTAAAACCGAAGATTACGCATTTCACGACTCTAATTTTTAGAGACTGCTAGACAGGATATCAGCCACGGTGCGTCCTTCCTGTATCGCTACGTACTTGCTCCTCGCCTTCTATATAACGGTACTGGCGAATTCGACAATACCCTAATAGGAGCTGCGACTCTCTAGACGACCAGCATGCAGCTTATTTAAGTCACACAGATCGTAAGAGAGCCTCGCAATGCTCAGGATATCGGCTGCCCTAGAGGATTAGCGGGAGTTGGCTGGCGCTATTGAATGTGTCAGCAATGGCAGCTCCAGGATCGTCCAAGGAGCCGCTGGCCCGTCCCATATGGTCTTCGTATCAGTACTGATCAAAAGGCGCAGCGTGAATACGTTTTCCTCCATAACATCCAGTCAGTAGCTGATAACGTTCTCACCCACTGACTTCCAACAGGGGCGATGGACCTCCAGGCGAGCCATGGAGTTCGACCCCCTTGAGGTATAGTGTAGGAACGGGATAGGGATTAAAAGCGTTGTGGTTTACTCTAAGCAGGCTAAGAGGCATAATGTCAGCCCATCAGCGCGCGGTTAGACCTAGCCGATTGGCGCGTACCAGGAAGCCGTCCGTCAATTTACAATTGGTCGTAGTCGGGATACCATCTTGAAATGCGTAGTCCGTCGCGCTTCGGGGCGGGCTTGAAGTGATCATGTGCACCCTTTAAAGCCATAGCCATACAACGTACCTCGGCTGAGTAGGTTCATTCTCTTGGAAAAATACCGCTAAGATAGAGACACCTAAAGTAGGCTTCTTAATAGGGCATGTGTTTCCGCCTAGCGTTGACAGCATGTGATTAACCACTTGACCATCTGTCACGCGTCATGCTGAAGCTTACCCTTGATACACGGGCCGTTATCCAGACGCCTGGAAACTCGAATTCATCAAAATTCCTCCATTTCTCTGGCCCGACAATCCACTGTAGAGTGGGATCGGTGTAATACCCTGAGTTTTCTAAACGGCGACACCGATGCTATTTAGTATGCCACGCGCTTCGTACTGTTGAAAAGCAATTGGAACTGGATGTCTATCCCGTACTTTTAAGTCGTAGATCCGCATCATCCATGCTAATCGTCGTCATTAACCAATCACAGTCTTGCAAAACTCACACTGGCTGATTCTGTCCAGCGTTACCGCGGTCCTGTCCGATTAAGAGCTCTCTCTGCCTATTTTCAGTTCCCTCCAGGCGTAAGGGACTTGATGTACACGCTCGACGAGTGCGGCTCTCTGTGACTAGAAGTCACTCGGGCTAAAGACGACTAGAGGTTTTTTCTGCGATCTAATATTAACCATACCCTACACAAACGCCCACCGGTTTTTATCACAACCACAGTAGCGGAGACGTAAATCGTTGTGCACAGAAAGTTAGGTAAGTTATCAAAGGGCAAAAGAATTACAGGCCATATTCTTTCAGTGTGACCTTCGAGTGCGGATTAAGTCCGCGGCAAAAGCCTAGGGACGACATCTTAGTAGGCTATCTCCACCCAGTATCTGGCGCGACGTCAGGTGTCAGTACCATGCTCTTATGCCCCCCTTTAGGTCCACCTAAACCTCGAGGTCAGCGATTGACCCATGTAGATACTGGTAGACGTCGGTGCCACTATGATCGGTTTTGTCGTAATTCACGAGCATTTGTCATACTGTTAAAAACAAACTTTGACGACAGTTTGGTGCTAATTTGAGAACCCACGTGGGGCCTGCCGCCGGATGTACGGTATGATCTCACCGGGTCTCCATGATACCCCCATCAGCCTCATGTTCTGGCCCGTCCTCAGAAGCGAGCCCTCAGTCCTTTCTTAATCTCCAGTTACTTATCAGGGAGTCCAGAAGCTCCGGGTCTTCCAAATCCTCCGCGATGTCTTAGTCGACCCTAGGGACACCTAGAGGATAGTCGCATTTGTAGTGTAGCTGTCCGAGAGCAGAACGCTGCGGCAGGCGGACATTGAAGTTACGGCTATGTTATCAGTCATCCTCGGCTTATAAGAGGCTTTGGGAAAGTTGGGTTAGTGGCCCAAACGATGATATGCACCAACCAAACTCTTTCACAGCAATCCCGCAGAATAATTGCGGCGCGGACGGGCGATGGGCCAGCTGCTAGGGTAGCGACAAAAGGACCACCAGCTTCTGTCTGAAGACAGGGGCCACCAAACCACCCTTGTCCAACTCGTATGCCCGAACAAGAATCGAGATCGAATTGTCACTTATCATCCCGTACACAGTAGGTCCCGTCTACGTATTCCATGCGTTGCCGCAGGATTTACACCAAGTTTGGTCGCCGGTCCTCACTCGCTAACTACAGCTGTGTAAAGCGCGGGCGAGGGCGATGGATACGTACCCGAGGTTATCAGGCTGAATTGCTGGTGAACACTTAGGTACGACTCATACGCGGGAACCCGGCAGAACTGTACATTCGCGGTTTTTGTCCTCTAGCTATTTCCAAGAGCTGATCACGAGAAGTCTCTCCACGCACATCGCTGAAGCGAGACCCTCGCCAAGTGTTACTTATAGACTTCTATGCGGCGCCGCAGTTTATACAAGTCCTCGCTCATTTTAGTTCGTGCCTACACTGTCACTCCTACGGTACGCCACGGCGCGTGGTGATGAAAAGGTTTCAAGTTCGTATGCGAAAATACAGGCCATTTAACACGGACTCCGCGTCCGGGCGGGGCCGTAACGTTGCCCGTACCCGGACAGTTCCATTGTGAAGCACTACAGCTTCAATGTTACCAGTGTAACGCCAGCATCAAGAGTTGCAATGGTCTAAGCGTCACCTGAATTTGCTATATCCTGACGAGACAGGCGTGCCCCATCGGAATGGCAGAGGTAATAGGCAGCATCCCCGCGGATCTTCATCTGCCGTCAACAGCGCCGGATTTGTAGGCGGGGCGATAAGCACTCGGGGGTCATCGTTTAACCACCAAATGGGCAGTACAGGTGTTCTCCTGTCGGGCCGTGTAGTTAGTCCGACAGGTGAAACAATCTGTCAACGAATTGGCGCCTACTTGGTCCGCCAAGTGAGATCTTGAAATTACAAGTCTTTCCGGCGCAATCAGGCCACGATACTGGGGCAACACCCCGTTGGGACGACTGGTAGAAGCTGGACTCCGGGACGGGGCACAAGGCGGTGGCGGCATTGAACAAGCACGCACGCTCCTCCCTATACCTACGACAACTTAATCTTGTACCAGACAACCTAGGAACCCTCACTTGACTGCTCAAGCCGAAGGGAACAACCCCCTCCTTGGACAAAGCTTACTGCCAAGGCTTGGTACGTTCGCGTGTCCGTTCTGTATCGGGACCTGAATTGCGTGTGCAAGCGTCATTCGCCATGGCCACTACGGCCTGGTCGGGCACCCAGTGTGATAGTCTTTCATGCGAATGGCCCAGTGCTATCTTGTTCGCAACGTTCTGTAGATAGAAGGCCGTGGAAACTGCGACTATCCGCCGCACAACCTTCACGGGCCCCGCCTCTCTATGGAATACGTGTCTCATGTGCGATATGAAGGTTGCCCTCCATAAAGCAGATAGTGCTGATGTGCACTACTTGGTACTTTGAAACGTATTAGTCTCACCTGCTGATGATTCCTTTAAAGCGGTGCAAACAGCCTTCGGCAACCGGCCACTTAGGCTCGACGGACACCATGCCTTTCTGACTTACAAAATGACCACGCCCCTACGACAGCTGTCGTTACCAGGCATGCCTTAGCTGTCAATGGCCTCATCCTGCCTCCTAAGGGGGTATGTTCTCCTAGTAGCCATGTCATAAAACCCCTGCGCGAACCGGGTTATCTACGAACAGTACGAACCCGGCGCGTTTTGGCTAAAGTGGGGTTTATTCAGGGAGCCCGACATACCACAACAGTAACAATAACACACTAGCCGTTAGCAGGGTCGACGTGCTCCCGTTCGCGGAATTCTGGCTGAACGTAAATACGCACCTGAGCGAATTTTCCACGAACACTTTTACATTTAACCTCGCAAGAACCCTCCCCATTAACGAGCTGAAACGCTTATAAGAGAGACGTAATGGATCAGAGACCATCTCCTCCGAGAAAAGTCTGGGTGAATCTACGATGGGTATCTGGAACCATGCTCCCTCTTCCGGAGGACAAGCCCTTAATATGGAATCCAGACTAAAGCCATAGCGATAGCAGCTTAAAACTAAGGCACGTCGTCCAGCCAATTCGGCCGATTCCGTTTGGAACAAATAGCTGTCTGTCGCAAACACGACCCTGGGAAATGATCCAGTTCTACCGCACCAGAAGCGACCCACCCCGTATTCGCGTGGTGTTCCTTCAAAAACGCCCCCTTGGGACTCAAGACGTCGAACTTCTTTACCCCAACCGTTGCGGGGTGTGTGAGAAACCGCAGACTTGAGAGCCCGAGTATCTAATGCAATCTTCTCGGGTAACAAGTGTGTGTACATCGTGACAAGTCCTTGGGGTCTGCAACAGTATGTCCGACCAATTGACCGACCGCAGCATAGTCACAGTCGGAACTTTCGGAGTAAATCCAGGAGGGACGCCTATAAACTGTTCATAGGTGTCAAAACGGGCAAGGAACCAGAGAATGATTCAGTGCATTCGAAGAGTGGACGCGGTAACGACGTATAAATTTCGCGCTTCCAAGTAACACCGGACCGCGATGTGTGTCGCATACCGAGTTCTATGACGATGCTCAGAACCTTTGTCCACTAGCTTGCAGTTGCTCGACCCTAAGCGTTGATCCGATCTGTGTACAGAGAATCCACTTCTTATCTCCGTTGGCCATTAAAGCGTTTGTGTCCAGATCGGACTTGGTGTGTATGTAAGGCCTGATACCGCACAATAGGAAATATATCGGCTAAATTAAATTGGCTCGGGATAGCCGATCTCGAATACGTCCATTACTGAAGCAATTGGTTACGCGCGAGCCCCCGATATTGACTTTGATAGTATGTCCAAACGAGTACAAACTCGTTGCACTTAAGTTCGACTTGCTATGAAACATAGCCGTAGGAGGATTTAACCGAGCCACAGGCGGCTCCCTCTATCTTAGCGGATCGAAGTAATATTCTGTTGTCATGGCTTTAATTGGGAAATGGCTGCCGAAATTTGGCGAAAGATAACAAGTTAATAAGGACAATTCCTACTTACCAAGGGTACTGTTTCGCAGCGGCCGGTACCCCTTCGAGACTCTGTTGATTTTCCGTGTACACAGGCAAAATGCATTGTATATCCCGGATTGCTTGCTGCTCATTAGGACTTTACGACATTAAAAGCAGACCAATTTGACCCTGCTAACCATTAATCAAGGTAAGCTGCTCTTTCACGGAGAAAGCGCGTGTCTGACTGAGTATATCTAATAGAGTTAGCGTACAGTAGTGATTGGCATGCCATCGAGAGGCGACGTCCGTAGTCAACCTACACCGTTAGAGAACCCTTGTCCGTTGCGCTTCTTAATCTTTTGTCGAAGAGGAAGTACATGAAACAATCAGATTAGTCATTATGATACACATCGGTTGGGACACATAATCTTTGCGCTGCAATACCCTACAGTGGCTGAAAGAGTGGCGTTGCACGCGGACTAGGATTACAGCGTATGCCCAGGTTCTTCGTACGTTCCTATGGGGCTGTAACTTAGTATCAGACAAGCTTGCAGACCCGCGCCCGGGCACCGTGCTATCTGAGTGCATGCCGTCGGCGTAAATCGTGCAGTGATTCTCCTCCGCCAACGGCCCTGAACAGGGTTCGGTGCTACTACTGTGGCAGGGGGGCGGGGTGTATGTTACCACAGAAACTCCTCACGCGGCAGGGTTGACGGCCAGTATACGCTATGAAAGCCAACAATTGGAGTATGAATCCCTCACGAGGCTTAGCGATGCAGAAGCTCGCCTGTAGACTAGTCTTACTAAGTGAAGAAACGGCGGACGAAATCGAACGTGGGTTATGCTTCGATAGTCAACCATGAGTGCATTCAGTAGAAGGTCGGAGAATCCACTAGTGTGCGGAATTATGGGTTCCATCTAAGGCGAGAAGGGTCCGGGTTAAGTCCAGCTTCTACACTCAGCAGGCAAACATACGTGGCCAGGCTCCTTTTAATCCCCGGAACAACCCACTCCGGGGGGTGATCCCGAAAGATAGATTTATGTTGAACAGGCAGTAGCGATTAAGGCAGCGGGAGTGGACATATATAGCAGCAAATTGTCTCCCTCGGGCCTTAGCTCTAGCTCCGGATAACATAACATACCTGTGCATTTGGCAGCAATGATGATCTTGTGCTAGGTTGACACTGGTTGGCGGACAACGCCCAGTAATGGGACTAGCCTGTGGCAGTTTGAGTTTATGCGTGAGCACAGAAGCGCGCCCGTCTTAGGTTGCTTCACACGGCCGATGTCACGGCAAATTGGTTTCCAGGGAGAGATTGACGTGTCTTGAGTCTACGCTCCGCGTTAAATACACCCCCCCTGACCACGTTATTGTGCGTTTAGACCTATTCAGTTCAAGGCGTATGGGAAGACAGCCCGGTAACGTCGCGGTCGATGTCGAGATCCGCTGCGCCCGTTCATAGACGACAGCATGAGAATCGACGGTCTTGAACGTTAACAGATCTCAAAGTCGTTAGCATAAAGCTCCTAGACCAGTCCGTATTGCCGAATGTCCTTAGACTGATAGGCTATGGCTGCAGACTCACGCATCAGCCCGGCGGGGCTTCAGCGATCTAAAGCTCGCTCCGAAGAAGCTCGGGATACTCATGAAGGGAACTTGAAGAGTTATATCGAGCACGGAGAGACCACACATAGCCCTCTATAGATTTGTAAAATTAATGGGATTGTCATACATGCCAATGGTATGGGCTAGAGGCGCCTGTCAGTCAAGGAGATAATTCGTACTCCCTTACTTCAGGGTAGATCATGACAGTTCAGGTGAGGTCATCTAAGGAAGGTCGCTCGGCTGTAGGGGTCTCGTACTATTAGCCCACCTCAGCCCATCCGCCTTCACTCACATATTGTCCCCCTGGCCTAATGGAATGGAAGGTGATCACTCTGGTCGGGTACTACCACCATATAAACACTGTCGCTGTAATTGTGTTCACTAAATACGCAGTCGAACGTCCCCAGTCCACGTCCGGGTGATGCCGCGCTCCCAAGTGGAAGGTATCGATTTAGGAACCATCGATGCTAAAGACTGTATCCTCGTACGCAAGCTACCGGGAGACACCTCCGGGAGCAGTGTCGGTACGCTTGTATAACATCCTGACAAACGCGTTAGTTGAACATTAGGCGTGGTTCGCAAGGTCGGCACTCGCTGAGACAGTGTAAAGTTTGGCGGCTCGTTACCATGAGGCCTTTTCTTCTTGGGAGGTGTTAACCCAGGGCGTGTGCGTATACGCCATAGGACTTACTAAGTTGTGGACACCCGCCCGCCTTTTTAGTTTTAATAATGCCCGGCACCTTTGCTTATGCGATTGCAACATCGCTGCAATAAGCTCGCTGGACGTATCAGGCCGGAGAGATGCTATCGCGAAAGGATTCTTCCCTCGCAGCGCGTTCGCATTCTCATTTCGATAGAGCTCGATTAAATCACGGAACGCTATGGAACAAGTGTGCGGGACCGAGAGCAAAACGCACGTGTTAGCACCTTGACCTAAGAATTGGGGATAAGGATAGCCGAATGAATGCACTTAGATGCGTTTCGCCGCCTGCTACCACATGAGCTGAGACAATTAAGCGCAGAGATCATTGGTGCTGTCAGTGCAATACCTATGTGGGCCGCCTTACACTAATTAGACATCCGCAGCCGCCCATTTGCGGCACGAAGGGAAATCCGTTAAACACGGGCCGTCCGAAGTCCACAAGCACAGGTCCGTGACCCGTGATGGTTCTGTTTTAAGCCATCTTTTGGCGTTCTGTCGATGAAATGCTGAGGTTAAGTGCGCGAAGTTGCTTTCCGACGAGACTGCTCCCTGCCGGCGGGTACGCGTACAGACCCTGCGGTCCGCGGGCGTGATCTAGATTACAATCGACTTCCACGGCTATCATCCGCTCGTTTGCCATGGAGTCGTGACAACCAGTCTAATTGGGCTATATCCCCTGCGCGAGTACTCCGCGGCCATAGGTATGCGTTACAGCGTTCCGGAGCAAAGCGTGCACTAGTATCTTCATCCATGAGGTAGACGATAGGGGTGGGATCGACTCCGATGCTAATGTCTAAAGTCCCCACGCATCTATGTCCCATAACACATGACCTACAGACCTTCTGTTGTTAAGATGGTGTTTGTCCGATGAATCGTAAAGACTAGCTGACTGTACGCAAAACTAGGTAGTTTGCTATCTGACCATGGGGTTTGTCTCTGTCGCTTTCGAGGGAATAATTAAAATCCGGGATGCGGGTTTCAGGCCCACGTAAGGCATCCGACTATCTACCAGCATACACGAAATTCTAATGAGTTCAGATGCCGTCTAAACAGCTGATAGTGACTGCCATCCTAGAGGACTCGCTCTCTTCTTACCCATGAGGTACTGCGTCGGAGTTTACTGACCACCCCCGATCCAGCTAGAGCGATGAAAATTAAGTTTTACGGACCATAGATGGGGTGTATACATTTACAGCAAACAATCGCCCTTGCTCCTAGAGTTACATACACGCCTCTACGACCTGCCAGCCAGATCTCGTTATCGCCCAAGGCAAAACTTACCGCAACGCGAGGCGCCTTTGGGACGGCTGCCTCATATAGCCGCCATACACATGACTACCCAGCGACGTTTGTAGAAGCAATGGGCGAAGAAGGACGATTCGAACACTATCAGGGGTGCTTCAGTTTACCTGGAAACGACTTTCTCTGCGATCCTATTCACGTCCTAAAGCATCTCCGCTAACTCGACGTTGAGATGAGCCATTGGGCTGGAACAACAGTCAGCCCCTAATGAGGCTACCTCGACCAGTTTTGGTTGCAAAAATCCGCCCCCGGCTCTCCTTACAATTTGCGGTCGCTTAGAGACATCATTATTCACGGTCGCCAGGATACTATCCGTACGAGACCTATGCGTAGATTTAAGACCCGGCATTCGTTTTTCCGGTGTATAATGATTCAGTTATTACCATCCACATCTAACATCAAGAAAACCAGCAGGCGTGATCATGCTTTAGGTGGGTCCAGAGGATGACGACAGGCTCTTGCTTATATCCGTTCACTACTGAGGTCCCGGGGACCCACATAAGGAGCATTGGGCAAAATACGATTGCAGAAGGCCGCAGCTGTGCTACCAATTCTTGCCTTCCGTGTTTCCCTATCACTAAGACACCGCAAAGTCCATCAGGTCGAGTCATCCCCAGCCGGCAAGCAGATTCAGGTAACTACACAACCTCACTGAGCAGCGACGGCTTATAAAAGTGCGTTTGTTAACTTAGGTCTTTAGCTATAACACGTGGCTGATCACACTCATTCATGTATCATCGGCGCTAATGCGGCAAGTGGGAAGACATCTAACCGAGGGTAAGAGTTCTATCTTAGATCCGGTATCGTCAATACTGACGCGAAGTTGCGGACCATTGGAGTGCGCGCCCTCTGGCTGTTTGGGGTATTTCATCTCTGAACATTTAAACATGTAAGAGGTTGAACGATCATGACTCCAACCACCTTCGCCCAATTCGAACAAGTTGACGGCTGTGTGAGACCCGCTCATAATACCAATAAAGAAGGTCACAAAGCTTAGTGCACGTTTGATGTGAGCCCAGCCCGCTAGAGGCCTGCTAAAACCTGCAGCTGACAGGGGCGCCAAGACGCGAATCTGTTGTATTACAAATCAAAGAAACCGACACATTTTAGACTACGAGCCAATTACGATATCGGGCCCCCTTCCCGCCGAAGAGTTTGTCAGTCACATAATGATCGTATGTCACCGATACCCCTGGAGGGTCCAAATATAAAGAACAGTCATTTGTAATCTGGGAAGTCACAACATTTATGACAGGAGATAAGGTTATACAGCCTTGTAAGACTCGGATGATAATATTCGCTCTATTGACTGGCAAGTATTGCACTATTTGCGAATTAAGAAACACCCGCGTCCCAGCTCGACATTCCCGAGTGTTCATTCCTGGTCCCATCTTGACCGGGTATGGACTGGGTCCCTCGATGAGCACCTGTTCGCTATCATGTGGGCCGATACATCACACACCCTGATCAGGGGAGTGCCGAATTTGCACCGTCCCTGTGGCATGAAGTCTGGTGCACCGGTTACAGGGATAGCCATTGAATTCAGGGCCTCAATGTAACCAGTAAGAGCAGTGGGAAAATGCTGATGAGTTCGGATGTGGTTGTAGTCGACAGAGTACCGCGCATACTGCTTCTTGAAACGTCCGCGAGGGGATATTCGGCTTGTCGGATTATGGAATGGGATCTCATAAATCTTGAACAACGAAACACTACATGCGTCCCGACCGTGCCAAGTCATCTATTTAGAGTGCGCTTAATATATCGTAAGTAAGTCTGCAACTGTTCCGGCCGTACTTCTTTGTGGTTCCTCACAAGTATGAACCTTGTGCTCTATTCCACCGGAAGCTGGTGACTGCAATCAGAAATCGACCTGTTCTCGTTGACTGCACCGGCTGACGCTTTCATACTCTTATACGGACGAATGAATTTCTAGTTAAAGCCGCGACTTTTTAGGAACAGAGGCACCGGTTGTATCTTCGCCCGGAAATATTGGCAGCTTTTGTTGCGTAGTTATGGCCATACTAATACCGCCTCATTAGTCTATATTGTTTGGGCACATATATCATCACGCGTACCCGCCCAGTACTAACCATCAATGGCCTCTACGAGACAGTAACATTTTAAGACCCTTAGGCGACTCAAGAACTTCTCAGCAGGGTTCTCGCGAGATCATAATCTATTGCGGTTTCGTTAGCCATAGCAGCATCTTGTATTGTTATCATGTCAGGTATGCGCTCTTGTGAGTCTGACGAGTGGTCTTGTTAGTCGTTTCCACCGCTCGATGCGAGTGAGTGCAGACCGCTTCATGTTCTTCGGTTGCTCGGAATGGAATGGGGCACGCAGGCGACAGCCTACCGTCCTGCCTGGCGAGGGAAGATTTCAAAGTCGCTACCCGATCTGGGTTGTTTCTTAGTCGGCATATTGGAGGCGACTCATAGAACGTTACTTCAAACATGGGATTTCATAGTTGTTTTAGAGCCGCAAGTCTTACCACACGATTGCATAACTTGATCGTATTGCGAAGTTTGAGTCCGGGAAAAACAAACCTCTAATGATAACACATGTCTGCCGGACCGCCTTGCAGTTATCACCGATCCGGTTCATAGGGTAGCCAGCTTCGTATGACCTTAGCCGATTACTGTAGAGGCAATTGCAAAGTCAAAGCGAAATTCAGGCGTACCTCAGACATAAACGGGAACCTCGTCAGCAAGATCGGTAGACCTAGGCTACTCACGCAACGCGGTATATGCCCGGTTACTACGCGACCACGTGATGTAACCTGCTGTGTTTTACCTGGATTGCCATCGCTGGCAGATAAGTATACTAGTGATCGTGTATTCAGCATTAGGTTATTTAGAGAGAACCATCCACGTCAGGTTATTGTTGTTAACATCGTGTCGGGCTCCATCAGAGATATCCGATCTACCCTGTCAAACAACGCGAACACGAGACAACTTTTTGCGGCGCCATTTGGCCGCCAGCCGCAGGCCCCCAACGTGGTCTTACCATGAAGGGGAAGCACTTGGACGTGAAAACTGAGGTCGATTTAAGTTTGACATACAGGACTCTACGATGACCGTCGGGTGACCAATAAGGATCTACATCTCTATTCTTCGTAAGCACTGATGGTAGTATTCCAGTAATGGGAAGCTCGCAGCCACTTTGATGCTCGTTTGATAAACCCATATCGACCAAGAGCCGGCGGAGTGGCGGTTTGCTTATCAAATTCATACAGCCTGAATTTGGTTATCAGATGCCTAGCCCCTGAAACTGCAGCTCAAGCCACTGACTACAGAACTGCCCGTTTCGCCGACATCAACCCAATCGAAAGCACGATGAATCTATCGGTAAACTCATCTGTGGATCCAAACAGCATCGTTGGCCAGTACGATTTTTGCATCCCCTAGGACAGGCGGGTCCCTAGTCCGCTTGGGGCCACAGCTTGAAGGATTAGAACAAGTCGTGAGGATAGTGTTCTGTACTTTACTATAAGTATTTCGAAACTATCCATCCGTTGAGTTGACTCACGTTCGCCATGGGTTGAAGATGGACCTTCAATGGTCCAGTGTGCGCAAACAACCAGTAAACGTATTATCGTATCGAGGCAAGCGACTCATCACGAGCGCCTCGTTGGGATCGCAGAAGGGACGTAGCTGGTCACCCCAGCTATTAGGCCTGCATTGACTGCCCGCGTCATAATTCGTGCGACAGTCTATCCCGGTACTCAGCTCTACGTTATGTCTACTAGATACTCGGCTCTTGAACACCTTCCGGGCAGGACCGGAATCCCTGTTCCAGTGCACGATAAGAAGAGTTTTCGCTTCACTGCAATAAGCCGTCGATTACACAGTGAATGTAAAAAGAATGCTGGCCATGAAAGCATTGTACAACCATGCCCAGGAGGGTCTCGGACTCTCTTTCGGACAACCGCACTGGCCTTTAGAGCTGGAGCGCGGGTAAATTTCGAGGGGGTCGACTTTTTCGGGTGATTCCATATAGGCGATGTGAGACACGGAACATAATCTGTCACGATGGATGTGCCCCATGACGACCGTTGACGTACGACAACTCGAATTCAAGGAGAGTAACGAAGCGTCCGATATAAAGTCCCAACGTCTTCCGAGATCAGACCCAACTAGAGGATAATATTGTGCCAATAAAGACAGGCAAGCACTGTGGGGTCGTCAGTTTTGAGCCTAGCGTATCGGCAGAAGCTCGCAAATAAAGTCACTGACGCACATCGGGTAACGTGGTGTCCCACTGGATTTAGCATTGCAAACGGCTCAGAGCGCGGGATATCGGTGTTCTCGACTCCGAATGTATTGAGTGCGCCGAGTCGCCTCGTTATTCCGGCTTGAGTCGCTCTCTTCTGGGATATGAGAGAATGCTTTCAGCCTCTGACATCCGCCGCGCATGAGAGAGAGATGGAGATAATAGGGTGTTGGCATTCGGGAAGGGCGCTCAATGCCTACCTCGTTCCCCTCATGGTTCCCGCCTTAACTTGAGGAAAGATGGCCAGTGTACTCGGACCCCCATGGAAGATTGGTTTCCATAGATTCCAGCAGACCTAAACGCTATCTGTTCTAGCACGTAGGTCGGAAAAATAACGGCCGTAATTGGTTTTTTTCCCAATATTACAGCCCTTCCAGAATTACATATCGTCACCAACTAGGAATACAAAATCGAGCCAGATTCCCAAGCGCTCCCATATCTTTATGGTGCATTGATATAGCCAAACCCTGGTAGAGAAAGGGTGGGCGTACATCGTCAACTCTTCTGAGTAAAGTCTCAATTGAAGTGTCTTACAAAACGATCCGATATCGACTAGCTGTCTCTGTTCCTTCGGTGCCCAATAGACATTGACAAGCTGTGAAATGTTGGTTGCACTAACTTTGGGAAGCTGCTACAAATGGCATAACGATTACGACCGACGGGCTCTATTCCCTTTTGCCCCATCCTACTCTGTTATCTCGCAAATCCCAGATGTGCGACCTCCTAAACAGACAGAGTGGTGTTCCCGCGATCTGCTAGAAGCAGAGTGGTCTGGGTACGACGTACCTTCCTCGCGGAAAGTTAACGGGAGGGTTACCCTCCTGATTAAGCTCCGCGCCCTCCATCACGACTCCGATGGCCCGTTCAAACGACCCACTCGATATAACAGGACTAAGCCACCGCGCAGGGACCGCTTGACCTATCGCCAGCCCGTTGCTGGGGGAGCCTTGCTTTGCAAAATTAAGCCCCGAACCGGACATTTGCGGTCATTGCAAGGGCAGATCTACTCGTAAAGTTTCCCAGTATCGAATAGCTACGAGTAAACGGAAGCATAAACGCATCAGTTATTCCGGGAAGCTCTCTTTAACGTTGCTATCTCGGTATTAAACTCATTTTTGCCTCCGTCACTTGACCCCACCGGAGACAAAAGGAAGCGCGCTCTAGGCGAGGTATCTACTCGTAACCGCATCCACCCGAGCGTGGGTATTTGGCCTTGGTAAGGAATCTATCGATCATCTGACACGCTACTCCGGCTCTAAATAGCTTCGTTACGGGGACTATTCACAAATCACTGGAACCCATCTTTGTAAAATTGGGGGGCTGGGGCCATACTCAGTAACTAGGCGGTTTCGTTATCCACAGTAAGCTAGCTTGCCCCTTCAGTACAAGATTCAGCACTCTATGTCTCATTGCGGGTGCGGTCCTGAATGACTGTATTTCTCCAAAAGTCCTCTGAAGCGTCATCATCGTCAAGCTCCTTATCCTCTCTAATTGTCAATATTCAGATGTTGCGTCCATCGGAGCTCGGTATGGCGTGATAATACCAGAAACGTGTTAAATGAATGCTGACGGAAGCCGTTCGACCATTCCCCGAGAGTGCATGGTCGTGTGGCGACAGATCCTTCATTTACGCTACACTTTTGGCGGTTAGACCTCACCTTCCAGGTGTGTCGTGCGCATCATTCGGCGCAAATGACAGGTTTTGCCGACTTGACGCCCTATCCGTGGCACCCCCCTACCTTCGTGAGCGTTGGCCCTGCGGCACTTCCCCAAACCCTGTACATCGTGGGAGATCAGAGACACTCATAAGTACTAGCGTTGGAAGAACCGGTGTTGGCGGGTGTCAGCTCTCTCTGTATCACATACTCTGAAGTCCTACCAAGAGGGACGCTGCCTACGCTACGCCCAGGTAAAGGCATTGGACTGCTTGTTTTGTTCGGCGTCGCCCATTCACTACATCGTACCCAACGGTCTAAATTGTTGGACCAATTTGTTCCACGGATGGGCGAGCTGCATCACCTCACAGCGGAACCCCTTCATAATTCGCGACCTTCCCGCAAGGTGAGGTATAAGGAAAAAACGGCATCCCGTGCAGTCGCGGACCGCCACTGGACAGGTTCTGAGTACTAGATGGGTGTGGCCGAGAAGATCCGGACTAAAAGTCGCCTCAATCATCCGTTACCAGTTTCTAAGTGTATACGTGAGCGACACATTAGCTCTGGGTTTCACCACCAGTCGAATGCGTCAATTCAAAATTGGCGTCCTCGAACACGCTTTACGAGCGATGCTCATCGCGACACTCCAGTCACTGTTAAAGGTGTTCCGTTAAGGCAAGAGCAGCTCCACATATAACGTCCATGACATGTTGCAAGCCTGCACCATACGTCCTTTTGGAGCCGTAACCTTTTCCGGAAAGAGGATTCAGGTCAGCATTTTAGGTCTCTATTAGTGACATTGCGGATTCGCTCCGTTAACTCAAGGCCATCATTTTGGGCACTCCTCGGAGGGACCTAATTTTACTCCTACTTGCGCGATATCGATTGACAAAAGGAATTGCGTCGTATTTTCCATTGATATAAAGTGTACTTACGGCCCTGACATATCCTCACGGACACGCCAACACCACCCCGCCGTTCACGTGCCCCCCCTCGGGCTACCAACTGCACAAGGGCACCACAGCTTGACATCCATCAGCATGTTTTTTCGACTATTCGGCCGGCACCAAGTTGACACCGCCGACTGACGCGTGGTCAGCCGATCAGAGGCACCAAAACGGGGTCGCATGCCTTAGACGAATAAGGGTGCCATCGATGTTGGGTATTATTACCGAAACATTCGGATTAATAGTTGAAATAAACCTCCTATTCCAGAGTACTTACCCTAGACCTCAAATAAGACCTGCGAGTGGATGGTCTTAACAATCGGGTGGTCGTGGTCCCGGTTTGGGATAGCGAAGGATAGGGCAAGAGGACGTCCAAGTCCAGTAAACTCCAAACAGCACGCTCACTCTAACAGGGCGGTGATAATGGGGTAGTTAGACGAGCACTCATCGAGCAGTACTTGCAACTGTCTTTCTCCAAGCGACGCTTGTCCCAATGGCATCCGTAGACGACGATGTGTCGGTCCGCCGTCAGGGGAATTATTCGTATGATGCCTCGAGTCGGTCTCGGGAACTTTTCTCGGTTTCCGGTTCCTAGGGTTGCATCCCTAGGTCCAATAATCATCTGTCGTGAAGGGGCGAGTCCTTCGGGGAGATGCTAATTTCTATTGGCCCCAACCAATTTTATGAAGTGTCGGGCGGCGATGTAGTAAAATTTATTTCTATACCATGAAGAGTGCTCAAAGACTGATCCAGGTTCTGTCAAGCTTTTTCTACTATCTATGAGACCCTAGCCCACTATGCACTGGATACGATAACGATGCTAAGGACTACGATGATGCGTGCGGGTATTTACGCTTTGTTGGTTACCATAACACCCACAACGGATCTCTTATGGTTCTTTGATACTTTAAGATCCTTACAATATATCAGACATGTCTACAAGCCCATTCGGTGAATTCTTTTCTCTCTGAAGAGGGTTTTGGCGTTCAACCGGGTATGCTGAAAAGCGACTAAAGTTAGCGCGAGAAACATTATAACACAAGCTCGCTGTCTTAGCAGGTCGGGCTATGCCCAGGAGGGGAACGATGATGGACACGTGTACTTGTGCGACCGGTCATGGACATATCTCTCCGTTGGAGCGTCCGTTCCCAAATGGAGAGAGACTGTGACAGTTATCTACAACTGCCGGTAGCCGTGCCCACTCCTACGGTACCGCTAGTCACAGGGATAGCAGGAAGTTAGTCCCAGTTAGCCATCACGCGGAAGTTATTGACCGTCTGAGTTATTGTTCCCATTATGAGCCTAGCTGAGATGAGTCTCAGCGCGGCTCCGCCTGTTGATTAAAATGTTTCCAGATTAGGTACTTCCATGAACTGATTTGCTCATACATTGACGGCGGGCGAGATGACTACGCTTGCCGACTACGTGGGCTCGGCTCACAAGCTGCGCGGAGTGATCGAAATCAAGTCAGTTGCACATAGCCTCACCCAGCACCCTTGACCGGAGCAAAAGTGCTGAATGACTGCCCGCGCAACAGCTCATGTCTAACTATAGGTCCAAGGAGACAACTTGGAGAACGTTCCTGCGCAATGCTCCCAAGGTAGCCATGTGCCAGGTAAACGCCTGCTAATCTAGTTAAGGTTACACACTAGAGGGGTCCCATTATTGCTCACGTGGGCCACGTGCTACACTTCGCCCATAGCGTACGGTCTTTCACTAGTTCCGGGTACCCACATTACGTACGTTCGTTCACTACTCGCTCAGTAGCTAAGATCGGGCTCTGGGGAGTTCCAATAGAGCCAGGTCCGAGCCATCAATTGTCTGACATATTTTAACTCTAGAACTAAAGCAGCCCAGGTGGGAAGGCCACAAAGGAGCAGCCGGAGACTATCAGATAAATACATACGCACCACTAGTCGTCATAAATAAAGGAGTTGTCCCCATGCTACTTAGGATTCAACGGCTGGTAACGGGACGACAAATAGGATTACGGTTCTGTCTTAGTAAGGCTTATTCTATGGAATGGGGACGTTGGGCCTTCAAGAACGTAAGGGAATGTCAAGTCCGGCTTGGTTTTTTCCTGATAGGCGTGATACGCGAGCTTTTGAGTGTAATAGCGGGAGTGTCTGTTGTTAGATTACTTTTTCCGTAGTATCTCACTCAAACTAAATTAACACCAGTAGGTATTATACGCGGAATCTTCCGCTTTTGACGTAGAGCATCCCGTGTCCAAACCGAATTGTCCTTTTTGGATCGCATGACATAAGGTTAAGAATTTACCACCACTCGTAGGGAAAGACCAAAGCGGGACAGACAACTGCCAGCGGGGCATAGCCTACTTCCTGTTATATCAAGCTCCAGCTGACTCAGAACCAGAGTCAGTAACGCCTATCTCTGACCTTTGGGTACTCCCACGCGGTATCATTGGCGACCAGCTTGTGGAGGATCCATTTAGCCACTCAACTTGTTTCTAGTAGAATTGAATAGACACTGGAGAGATGGCCAGCGACTGATCTTGTCATACACTTGTAGGTACTGTACCTAAGGTGGTTCAATCCTGGCTACGGGTAACAGTTGGTGAGGTGGGCCCTTCCTTGCGTTTGATGGGGGCAGCCTCGTTGGGACCGACTACCTAACCAGGTATGGTTTCCTCGCAAAGCATGGGCCGCCAGTATCAACTTGAATTCCCGGATTACGTAGCAGATTACTCCTGTAGTTCTTACACGCCCTCCTCTAGAGAGGAGCCGCCACATAGGGTACGCTCGTCCTGGGGATATTCACTATACGACTGTGTACTCCCTGGCACTGCGCAATAACCGGAAATAGGAACATGATAGCAAATCACAGGCATTGACCCCAGTGAACAATACCAACCTCAGAAAATGGGGGAACACCCTGCACCTCCGTGCTGCCTATAATACCTCATATCGTCGGCTCTCCATATGAGGGATAAAGATTCTTGTGCTTCGAATTTCAGACAGTCGACCAGTAGAGCAGAATAATAATCGTCGACCTGGTCAGTAAGGGGGCCGGCTAACGTAGACGTTCCCTCACGACCGCTCAACGTGTCTAGACAAGCACACAGCATATTCCGTCCGGATCCACCAGTGTATATTGGTAAGTTGCTCCCAACTGGTCAGGATGATCCTCGAAATTATTTTGGATAAATAGATACAATGCCTATCCACCCAGGTAACACCACTGGTACGCTATTTAACGCCTTCTCCCGGGTCGCTTAACTAAGTATGCTACACCCACATGCTTCAAATATGGTCGTTTCACCCTGTCGGTAGACTCGTCAGACCTTGTCTCATACCCAGTGATTTCAACCGACCAGTGGTGATATAGTAGACCCTGGCGGTAACGATGTATCCTTATTGACTCACCTCAACCCCCTGTTCACACACATTACGCCCCGTCCGGGGCGAGTAGTGCTGCCAGGATTTTGGGGATACAAAAGGTCTCTTCCTTAGCGGTGTAGGGGCGGATTTACCTGTTTCTCAGGTTAGAGTCACATAAGCTCTGAGATAGATATGAGGGCGTCATAGGTTCGCACCGGACATACCTCGCATGTCCCCCTGGCGTAGCCACAAGGTGACTAGAGCCCACCCTGTCCGCGACCTTATGGCCCACATCTCGCTACTCACACCATTGATGTAATAGGGGAGTTATCCTTCGTTCAAGTCCGTTACCAGGTTCATCAAACAAGCTTTACGGATTGAAGCATCCCGGTAAAGACAGTAGCATGACTCCAAGGGCATTTTATAGCCTTAAAGGGCGTCCATGCGGGCCGGCAAGCCACTAAACCTTCATCTCGGACTGTTGGTCCTCTTTGCAAATTCATGAATGCTTTATGCTGGGAGACTAAGAACTTTTGAGGTTTCTATAGTTCAGCGGTGCGACGAAGTGGTCAGGCGCTGTAAATGAATGGAATACTCCTAGCGGGTTACCCCAGGCTTGAGGTTTTCCTAATAAACCCACAGCGTGGATCTCACCCAAGGCGCTAAGCCATAAATCAAGTCCCTAAATGTCCTTTTTAGAGCAAATGATCAGATCTCTGCGCGAAATTTGATCAATGTAGGACCGCAAAACCGCGAAGTCCCGCTGCAATCAAAAGGCGTTATACCGCCACCATTCCCGTGTGCAAATATATAGGCGACACCGCTGCAAAGCTCGGCTCATGCGATCATAACCCCACGCATAGCTTCCTCAATGTTATTTGCACTTCCCCCATCACACTGATATGCCCGGATGAACACCATTCGGGGTTTAATAGCCAGAAGATCCGCCTGCCTAAGATAGATTGTGGTTTCACCGAAGTAATGCCAAGCCAGTAGGTGACAAGACTGTTATCCATTCACGGGTGTAATATTTGGCGGTTCTCCTACAGGGTCGTTCCATGTGCAATGGGCCCTCTTACGACCCCGAGCAGCCTGAAGTCTGTCGAATTAATCTTATTCCTCAGCCCGCGGTCAGGAGGGCCGTAGGTCATACAATCAAGTGAACTCTGGCAGCGTGACGGCAGAAATGCGTAAGAACAGGGCTGTAACGATCCATGCCGGGTCAAGAGAAGGCAAACGGGGCTCTAACGTCCGATCTCGACGAAAATCGGAGGAACCGTCGCTAAATCGCTGTGCGCATTATTTACTCGGCTCTCTCTTGCCCATAAGTTTCTAGGTACGTACGCACCAATAGACAGGGGTATGTACTTTCGGGTAAGCACTGATCGTGGTGTTGTCAATCGGCTTCACTAGTGCTAGTGCTGAGAGTTCACTGTCCTTCTTCCGTGCTAGTTAATGAACCGCTTTCTATCCGGAGCGGTCTTCTTTCGCTCACTTGTAACATGCGCTAGTGGCACTACCGACAAGCAAAGCTAAGGTGCCTCCTCATCGACCGGAGGTCCCTCCGAGTTTAGACGAGCTTTGTTCACTCAAAACGAACACGCTGCGCATAGAGCAGGAATCAGTAAAGGGAACAACCTAACTGCAAACACGTGGCGGCTTGTCGTGTCTGACTACCGGGCAGTTCGGGTCCTAGGCGGTTAGTGAGCGGAACGCGTCGCCGGGCGTATCCGTAAGGATTGAAATAATTCTCTAAACGCCCCGCGTCGAATCTATGTCCCTTAGGCTGTGCCCGTCATTTCCGAAGCGCCCACAGGTAAGAAAAGATGGGTTTTGCAAGGCAAGGTTGCCGATTGGCGTTCGCAGCTGTTTAACAGCACATGCCGCGTGCTATACGGCAAGGAGAGCCTCTACTCATGACCGTCATCACACGCCATATGCCGTGAACCCCCCCGAGGAGTAAAGCGATGTTCTGCTGTACTTACTTCACAATTGTTAGCCGTGGAATTCGCATTCATTCCAACCGTTTCAATGATTCGAGCAGGCGAGGCTCCTGGGTGTTTCGTAGCAGGGCCCAACCACGAACATCTCCTTAAGCATCCACCCACGTGTAGTATGCACACCATAGATGGCATATGATTGTTCGAATGCTACCGTGATGCGCCTGTCTGACCAAATACCCTGAAGTTGCGGGCGCTTGTCCAAAATATGTAGGCGGGACACAGGGCCAACGTATTCCCTACGTCCGTGTACCTAGCTCAGGGCAAGTTTCTTCAGATTCCATTGGGACCCTGTAATAAGCAGCTTTTAAATTACGCTCCCTTCAACGAGACGGAAGCGATTCCGAAGCACCGAACCCTCAGAAATGGACATAGCTGGTGTTGTGGTGAAGCCTGAAATCCGACTCGGTACTATTTGTCATGGGGCTCCGGATATTTGTTGATCTTCGCTGCATTTGCGTCAAACTACGACACAAGTAGGATGGGCGTACCGCGAATTCATGACATGCGCCCCGACTATCATGAGCCAGAATGTAGAATCCAGGCAGTACCATTGGGAATGATTCCGTTGATTTGCAGACGGCGCATTCACTCTAAAGACACATATTGCAAGATTAACCTTCACTTTAACTCATGTCTCATACGGGTTGTACCAGCTGCTAACAACTTGACGTGGATGGCCGGGAAAAGACAGTAGTGGGTAAGAGGCATCTATCAGCGATACCACTTTGAATATGAATTATCCTATTAGAACCGTTCGCGTCGGCTTCTTAAAGTTAAAGGTCAAGAAGCGCCGGCCATCGTTAGGGCACATAGTGGCTATGAGTTGCGAACGTCATAAAACTCGTATTTAGCGAGGTCTCGGGACAGGATAGGGTTGCTGCGTAATTGTACGCGGCAGACAGTACAAACGTGCGCGCGGCGACTCCTATCTCTCCCGCTTAAGCTTTATATCAGCCTGCGCCGGGTGTGCGCGCGAAGCGAGTCTGAGTCCCGGTCGCTAGTGATAAGAAGGCACGTGCTCCCGAATTGCCCCCCTCTAAGGTGTGGTCCTGACGAGACTTTGGATCACGCCTCTGCACAACCAGGGGTTAGCAAGAAAAGCCCAACCTCCTTGACGGCCGTTCGCCCAATTGTAATGTCCGATATTAGGCGAGCTCAAAGTTATCGGGTGCTAAAGCTTCCACTTATCTTTAGAGGGCGCACAGTTGAGGTACGGGCCCGAGAATCGGTTCTGCCACGTAGACTCTTATGTGGTGTCGTATGTGGCGTAGTTCAACCGCGTCACGACGAATCGTCATAAAGGGTAAACTATCCCTAAGGGTTTTGGAATCTTGCGCAATAGTCGCCTTTGAACGGAAGAAGCCTTACCCCTCTGCGTTCACAGGGTAGCACAAGCTGCGACGAGAGTTACTGGTTGTTTGAGGGGTGCCCTAGTAGGACCTCCGCCGTATTATGTACTATCATCCGAGTGGGCCACCGCGCCCGCCTTAAACACATGCTACCAGTCTGTGCGAGTTGCAGGTGGATCGGCAAGGGGGGGTCCGCTACGCATGTAACCATAGGGGAGGGGTAGCAAAGGTGCGAGGACCACATGCCGGCGTAAAAACGAACTCTCACATGTCAGGCTTTGCATTCTGCGCCCCATAATCATCTAGGCTTTGCCCCACCGTAGCGAAACAGTTAATGCTTTGTCGCTCGTGGCTTAACTTCCTACGCGTTCTAGTTGCTACCCGAAGCGGCGTGTGGAGTCTGCGTTTTTAAGACCGGTGTAGTTCGCATGCAGACGTGAGACCCGAGTTGTGCTTGTGCCTTGTGGTACAACTCCACATATAGTCGCAGTGCGCACGCAAGGCGCACTTCGTCGCTGGCCGGGTCGGGTCGTACGTGCGTTACGAAGCAAAGAGTTGTTTATTAGAACGCTGTGATCCGCACGTAAGACCCGTTACTAGCTGCTCCTCTGTTCTTGCAAGGAGTGGTCAGCACGTATACCAGAACAATATCCTGTTAGAACTGTTAGACATACGACACTTCTCCACCTGGGATACGTAGGAAGGTGCCCCCTCACAACTGATGTCTTCCGCATCGCAAGACAACGTTGCAAAATATTACCCAGCGCCGCGCGTAGTGTGCACGTGCTGGTCCCTCGCAGTACCGACGGTAGATTTAACTCCTAAGTCGTTAAAAAAATTGTGATTCTACGAGGAGAGGCCTACGGGTTCTTTCACCAATTCGATAACTTTCCGACCGTCATATTCCCAATGAATGGAATTGAACTGGACAACATATTACTGACATAGAATCATGCGAGTGATCAAGAGTTCAGGAGTAACAGGTGATAACCTCGGTCGTGGGCCCGCGATTAAACAGACCTTAATGCACTGGATCAACGTTATAACTTCTCTGTAATTGGACATATCTTGTATCCTACCCAGACACTGAGGCACGCGGCTGGCAAGCCCCCAGGACAAGTTCATGCTGCGATGGGCTTTATTCGGACTGCCGGGCCTGACCAAGGCCGATCTATGAGTAGGGCGCGGTAAGAGCGAGCCCCGTTGTCCCAGCCGTGCTGAGGGCCATCTGCCTGGTAAGATACACAAGAAATACGCCTAAATGTTCGAAGAAGGCCTTAGATGATGAAACGTTCTAAACATGCGCGCTAACAGGCCACACTGTATGACATTGCCAGTCTCAATGGGGGATACACTTGAATTAGCCAATGTCTTGCCTCGCCTGACACCACTCGACTTCGCTGCACGGAGCAGCGCTTTTCCTTCAGTAAGCCTATAAGGGGATCTCTCTAGTCACGAACTGCGGTTTAACCCGAGAAGACGTTCCTAGTGAGAGCGCGAGCTCCGAGTACGTTCGGCTAGACTCCGTGAATGGGAGACTTAGGAACTAAGCAGCGCGGGGTTTCGTTTATTGGTACTTGTGCTTGAGCGGACGGGAGCACTTCCTGAGGCACATGCCGGGCGGGGTCGCAGGTAGGCTTAGCAGAGACCAGTAGCTCGTCCGCCTTTCCTCCCGAGCGTGAAAGCGGTAGCCATACACGGGGCTAATAGGGAGCGCACCATGCCCACAGTAGGCCAGCCCGGGCCTCACTCCCCCCATTTTCAGGCTACCTGCAGAGCCATTCGGGTTCCGTGGCGTTTCAGAGAGACCTGACTATCGGTTTGTGTCAGCCGATAGTCTTGCGATGTAACACACGAAGGGATAAAAAAGCGGCCGCAGTGTAGTACCAGAGGTATTTAAACGTTAGACCGAAATTGAGTTTTCGAGCCTATCGAATAATTTCGCTAGGGCTAGGTGATCCATTGGTTGAATTTGCACGCTTGCAAATACAGGCAGTGTGTCATCCAGCTCGCCATAAATGTTCAGGCGACTGACAAGAATTCGAAACTCACACGCACTAGTATTAAGCTTGGGTCACCCTGAGGCACGGGCGATTGTTCCGGGATTGATATCGGACGCCGCTTTTTAAACGATGTACAATTATCATATTTAGCCCATAGGCTCGATCATTCAGCCTTATGCGAACCTCGAAGGCAGGCGGAGTTAGTCGCAGTCCTCAAGGTGCCTCGTAACAAATAATGGGCAGCGCCTGACAAGGGTTGATGTACACTCTCACAACACTCTTAATTCAAAGGAGCCCGCTTATGGATAAAACTAATCCCAGCATTATCTCTCTAGGCTTTTTTTGGGAAGCTTAATCTCACACCTTAATTCCTCGTTCGCGGCCCCGTTGACAAACCTCGACGCCCAGCCTTATAGGAACATTAGATACTCGAAATATGGCAGCGAGAAAGTCCGAAGTGGCTACAAAATGACAATTGTCTACATCGGGAGTATTGCCTCGGTCTTTGGTTGATTGGAACGGGGTTGCATAAAGTACGCGTACATATCGTTGCCGGATAGATAATCTCAGTATTATTCTATTTCATGTGTGTGTAACGGCTACTCCGAAGTCCTGTCAATCAAGACGGGGGCAAGCACAACAGTTCACTCACGGATAGCAGATTATTTACGGCTGAGTTCAATATCGGCAGGAGGAATTAATTTGAACGAAAATACACGCCCCCGGGCTACTGTTTAGCAAGACTATCATACGCAAATACTATGCCATTGCTCGGTGGAATTTCGTTTCCGGACCATGATAAACCGTGTTGTTATTCCAAAAGCGAAAATTTTGATTTAGATCGGACCCTAGCATCCAATGCAGGATCTAAAATAATAATGCGGATAAAATGATAAATTCCCTGCGATCGACGGACGCTAAGTATTGAAGAGCATATAAGAATTGAACGGGTGGCTCCTTCGGTTATGTGGCACTGTTTGCTTGCCTGGCAGAGTATATCAACAGTGATCAACGCGGGAAACTCGGCCGCGGTCCGATGCTGTCTGCTTGGTTACCTCCGGTTTACCATCTGGTTCTACGTCCACTTCGTGCATTTTTGTTGGGTAGGCGCACCTGATGAATTGAGCTGCCCCCGATTTCGCACGTCTGACATCCGAATTTTTTGTCTCAACTTGTCAATTCCGGATCGTCCTAGCTCAGAACCCACGGATCAGCTCGGATAATTTGTTTGGTTGTTTTTACACGTTTATCATACGAGCACAATGGATGGGGCTCATACCCCGGCCCTGCCGGCGTGTGACGAGTGGAGATATTCCTTCTCTAGCTGTTCCTTGTGTAGGAGCACGCTTGGTCCTAACCGTAGCCACTTCGCGATATTGAATGGTTATGTTGCAGCTACAACCAGAACTGGTTGAGGGAGCCCCGAGCCTCGATCGTCTTCACGTCCATACGCATTCGCCACCCTAGCTGGGCTTAGACGTTAAACTGCGACCGGGTAATTACCTAATTCAGTCAAGCGTCCCGTTCCACATTAATATTCCAGATTTGCTTAATGGCCCAGTTAAATCTATCATTACGTAATAGCTGTTACTCCCTAAAGCGCCAAACTTTTGACCCCTTGTTACTTACAAATAAACGGGTTGCGTCTTTCTTTCCACGGACCTCCATGCTCGAATATTGTCTCTTTCCGTATTGTACTGTACAACTCGGTGACAGTTCGTAACTACCTTCAATAGCAACCAACCCCTGTTACACCCGTCGGGCTACTAGTTTCTCTTTACAGCCAGCGTCTGCAGGTAGCTCAGCCCTCAGATTCAGACACAATATGAGGCTCAACTTTGCACTGAGTCCGTGGCCGGAGGGCTCTGGCTAACGGTTACGTTAGCATGAAGTACTGGCTTCATAGAGCCGGGCCTAGTCACACTGGTTGGACACTACCCGGATAGAACGCAAGTTATAAGATATAGGGCAGGTTCTGGGGTGTGCCTGGATATTTTTTGTCCCAGGTTCCTTGCGGCATTGCGTTCAAGGTCTCTCTTACCCAGTCGTCATATACAAGATAATACTATCGACAATCTTGACAACGTCTGTTGAGAGCTCGCGTCATAGGGACGGCAGCGCTAGGGAGGTATGCCCAACCGGGAATGTGGGGTTCTCCACACCGTATGTCCGATGGGCACAACTAGACCGTGTCATTATAAGAAGCTACAACCGAGATGCCGCACCTCTTTAATGTTGATCCTGTATTGTGAACTATCACTCAGCTAATTCGGGGCCATAGGATATAGGCTTCTAAGTCGACTTTTCCGATGAAAGATCACTATCCAGCGTGTCAAGGGTAAATGACATCAGGACGCTGACAATTTGGCTGAATCCTTGGCGACGCGGCAAGAATAAAGGCATAGCACGGGCGTTTGAGGGGACGCTGATTGGCTCGGGTCCAGGTCTGACCTCCACGGAGTCCGGATTCGAACTCGGTCAGTCACACGGGAGGCTTAGGAGCCTTCGAACGGACGATAATATCCCGTTACTCGCCACTGTGCCTGCCTATAATGGAAAAGACAACTTTTTGGAAGGAGCTCGCATTGTCCGCGGCCGAGCGATTTCATGTGGCTTTGTGAAAGAACTCGAGTTGGACATAATGTCTGTATATGTATCGCCGACGCGACATATCCTGTACGTGTTGTCGATGATATGAAATTGACCTACTTACATGATACCAAAAGGAGGCGGCCCCCGGAAGGTTGGCCCGAAACACGAGCTCCTCGCAAATGATGTCATGACGATGGCAGAAGCCGAGCTCACGTCTCATTCGGTCGCAAATCCTTGATTCGTGCCGTAAGGAACTTGGGAGGGTAATAGCAGGTGCCACGTTCTCCTATTGTCGGACGCAGTGCTTATGTAACTGATTCCCTGAAACGTAAGCTATTTCGTCCGGAGATAGAACATTATGTCCACAAGGCAAGATATGTTTCCTATGAGAAGAAAACGACGCTTAATGACTTGGTGTTCTTTCTCCAGGCAAGATACGCGAGCGCCTACGGAACAAATGACGTCGTCTACGACGTCCAGATCCCAGCTTTTCGTTCGCTGCGGCCCCCAACTTTGCCAGTAGTGCCGATTGTGCGTTGCGGCAGGGGTCCTTCATACTAGTGCTTCATGCATTTGCCAGGTACCATGGATCTGCACTACTATCAACCGGGGACCGCGCCATCGCTTATGGGGTAGATGATCGCGCCACATCGTTAAGCGCGGATTATCGGAAGCAATCGTCCCACGTATCCTAGGTATAAGATATAAGTTGCAACCGCCACTAATCCCTCACACTTTCCACGGTGGAATCAGATGTCAAGCACTACAAACTTGGTCCACAGATGGGCAAATATATGTGCTCATCTCATAAAAGGTGTGACCGCTCGTTCCGGAACCTCAACTTTTGCTCGTAGCGGGTATTCCTGACGCGATTCACCAATCGGGGCCAACGGCTGACTTAGACCCGGCAAATAACACAGTCCAGCGTAGCTTGCGCATTTACGGCTTTTTGAGCTGGCGTTCCCGCCAGATTTGCACAATAACATCGATGAACCTGTGCTGCGGCTAAATGATAACGGAATGGACAGTTCGCAGTGCTTCTGATTGAGTTCGTGACCAAAGTCATCCGTAGGCAGGGCACTCTATACCTCACGTATGTAGCCTGTGTATCCTTGCCCAAAGGCGCGCGCAGCTCGAGGAGGCGGGATTGACCGGGACACATGTATTCGCCTCCGAGCGAACGCAGTAAATATTCATACGCAACGAAAGAGCTTCTTACGGTATTAACAATTTCATCCGGGGGTTATCGAGGATCCGCGCCACGGGTCTGCGCGAGACTCACGTGGCGGCGGATGAACCCGGCAACAGTCGGTGCCCCTGCTCAGCAGAGCGTTATTGCGAAGTCCATGAAAACCTTATTCACTAACCCGGAACAGCCCCTTTAATACCAAGTGTGAGTAGAATATTCACGCATGGGCAGGGTGTGGCGAAGAGGCGGCCACACATCGACCGGAAATCTCTGTCCTGCGTTCCATACCCCGACGAATTTCATTTCCCCACGGACTAACTTTCAGGGGGAATAAGCGAGGTACCCCTGGCAGAAAAGGCGCAATGTCTGATGAAATTTCTCGTGATGCTCGTGTGGACGATGGCAAAGCTCATGGAATTAGCTAGCAGCAGTGAAGTAAAAGCCGCTTCGGCGGCGACGGAGTGTATCACATCGGGTCGGATGTGGTCGCGGAGTGACGAGATCGAGGATGTGAGAGATAAGGCCCGTAGATCGGCAGGTGTGTGCCCTACGGCTCACTCGTGGTCAGCCAACTGAACTCGTGACCCTCGTTATGGATCTTAAGCTCTAGTAGGACAGCCCAACTACCACGTCTTAGAAGCCAACGATAAGCCCATAGGGCAATGTTTTTAAAGGAGCCCCCGTTCGTTTCGGCCACAATTAAGAATTGAGTTGATCATGAGGACTATGTGATTTAAAAAGTACACGAAAGGCGCTCAACGGAGTGTACTAGGCATTAATCATCCGAGTACATGCTATAGCTTGTCCAACACTGTGCGATGCGGCGAGCGCGGGTCTGAAACGCACCCGATATTGGTTATGTGTTGGGGTGCCCATCGCGCTGTGTCCCCGGTGGGAAAGTGATGTGCCATCATACAAACGATCGTAAATCTGCTGATAAGGACAGACGGAAGGCTAAAATGGAAAGATTGAGAATTGGGCGACTTTCTTTATTCTCAGAAGCAGGAATAGTCATCCGTAGTGCCGTCAGTTAGTAACAAATAGTTGCACGCTGCGGGGAAATCCCCCCACTCCCGGAGTACCCAGCAAGTTAGGAGGGTGAATCCCGGTTGGGCTCAGCGGACACATGGTGCCGACCAGTATTTCCGCATTTTACGGGACCCATACAACGCGTAACGCTTGACACTGGAAACAATAATAGATGTGTCATGAACTTCTAAAGGTCAGTTCTGTCGTCGATCAGTGCTCTCCGCGATACCCGAATGCGATTCTAAGAGTGCAGCTTTCCCTAATTTGCTACGCGACGTATAAATTGGCCTAGATTGATGGGTGGCGTAATGAAAAGTTATGCTGTTGGTTCGTATCCTGTGTATTTCGGTTCTTCAATTCGCACAGTGATTAACGGCCCATGACTGATGGACGTGGGCGTGTAGTATGGGTATACCCCCCTCAATCACCCCGAGTGCACCTTCGTGCGAGAAGCACATCGCCTACATGATTGGGTACCCCCTAGCTAATGACACCTCCGGCCGGTGCGGCGGAGTCGTAGAATGGGCCAATGATTCATCCCCTTGTTTCGTCAGTTCAGGTCCTGTGATGCACCGTACCTGCCTTATCATTCTCGAAGCCTGTTTAAGTTTCGTTTGCGAATTCTGCGGCCTGCTCTGATCCGGGGAGACCTTCGAACATGTGGTACCGAGACTGAGGTGAGTAGTTCAACCATTTAACTGGAACAGCTAAATGTCGCTTTCGCCCCTTACTTCTTGTATCTTTCGTGGCGTTACCATGAGGAGGGCATTTCTGACTGTCGCTTGGATGGAGGAGTAGAATAACCAGTACCCTATTCTGGCCCTGTCAGCGGCACCGGAAACCGGGCCGCACGTGTGTTCGCAGTCATTTGTTGACGAAGCATGCGTCCAGTGAAACGTATCAGGCATAACTTGCAGGGTAGGAAAATAGGCACTCGTAGCCTAGGTGCAAGGCGTTTTATGGCGCTAGAACTTAGAAACGAAAGATCCGGAGCTGTCCGATAACTAGTTTAAAGAATCACCATCGGGGGATTGCCAAACGATACTACCATTCCTTACACCAGTGAGGGGGCGCTTAGTGGGCATGGAGTTGACGCGGGATGCGCGGGCCAACAGATTCCAAAAAGTGACGCTATTTAAAGAGGTGGGCTATGGAATCGGCATGCTTACAGCTGCTCTTCCTCCTGTAGTAAGTATATGCGACCGATGGAGGTCAAAAGGTCTTGATTCGTCGGTGGCCGATGTTATGCGGTGAGATACCTCCCAACGGCGTTGATAAAGGAGGAGGCTTACCATTACGCCCATGTTCGAGCCCCCAGCCAGACATCGGTACCAAGAAGGGTAGTTGGATACACCCCGTTGCCACCAACGAGTGTCTTGTGATTGGCCGATTTCACCAAGGGCAGATCGACCTGGCGTGGAATTCCCTTATGCAACAGAGTCGACAGTTTGGGGTGTAACAATTGTGCGTAGGCCCAGCCGTCGAGTGGTCCAGGGCTGGTACTATACAGCTAGCCGTACAGAATACTCGAACATTGATCACCATGTGACACATCCGAATAAAGGCTAGCTACTTCCGCACAAGCAGATATATTGCCCCGAGTGGATTCCCTGGGGTCTCTGAGGTATGGGGATAACATACTTTTTAGGACTACAGATAAAAGTCTTACATGGAAACCAGCTACGCGTGGTAAACGGATAACGCCACCGGATGTTAATTGGCCTCGCGAGAAGTTTCATATGCACTTAGGGGTCTTAAGCCGTAGCGCTCGGTTTATGCGGCATTGCGAAGTCTGACGAGGCCATTCGACAAGTCCAACAACTTATCACACTTGGTTTGTGCTGGGCTGTGAAGTCTGCAATTGCAGGTAACTTAGCACTCCGTGATCTACACCCAACCGGCCGTACCTCTTGGGTAAAGAGACTGACCCGGGTGTGATATCTGTGGTAGCCAGGTGTTCATTCAAATAAAAATTGTCCTAGCATTCCGACTCTAATTTTCAAACCGTTGCAAAATTCATCGTTCTAAAAGCAATAGCTTGAGAGGTCCTTTTTTACGGGTCACTGCATCAATATTCTTTCCTCTACCACTCAGTTGATCTTAGTCACGGGTATAAAATATCCCTACTGTACTGTTTGCCGGGCGCGACGGTATATTACCCGTGGGGCGGCGCCATCCGATAGACTCGTATATATCAATCACTTCCGCGGAAATTTTCAGCGTGAGCCAATCGATTGACACAGAGTCCGGCACCGGGGTGACGCATTGAGGTCCATGACACTCGAAACTTGGGCTACGACAGGCGCGGGACGGCCGGCTCGTTACTGAACTGTCAATGGGGATCGCGTGCTTACGGTGCGCGAAGGATTTATTTGAACGAAGGCATCTTCTTAATTGTCTTCATTAAAATGGCCTGGTATATAGTTCGCTAGGCGTTTCTACAGTACGGGTAACTTTCTCTCAAGCAGGAACCGCAAACGTCGATGCTGCAGTGGCATTACGGGGTGATCTTAACATCAAGGAATATCTCCGGTGATTCGACACGTCTCCCCACTTAGCGCGTGACCTCTGACAGGTACCGACTGTAAAAGATCTACGTGTTATATTCAACATTATCCAGCAAGTCGTGGAGTGCGTACATGTTATTGTTTGTGTACTAGAACACTACTATGACGGGTGGAGCCATCATGGTTGACACGGAAGGATAAGGATTGCGCACCCATCAGGAACATGTACTAGACACTGCGCGTTACCACCATAAGCCAGTGCCAAGGATATTGGAACGCTAGGCTTACAGTAAGGCCACAAAGATGAGACTCCTAGATCGTCTGCCGTAATATAACAACTGTACTGCTACAACGACCGATATGCGCATGGCATGGATGCGTAGTTTTCAGGGCATTCGGTATACCGGAGCTGTGCCGAAATCACCGTTTCGGCCACGACGCTCACACGATGGTCTGTGAGACAGGGGGGCTCGCAATCTTCCCCATGAACATGGCGTGATTCAAGAGGAAGCGGTGGCGTGTTCGTAGGCGGGGCGCTTTTCATTTCACGAGAGTAAGACAATAGCAAAGTGACGGCCACGATAAGGGAACTAGAGAAACGAAATTATATTACACGTGCAGTCCGGATGGCCTTGCTGATGTAGCTACATGTCCCACTATTCGCGTTGCTACAGGGGGTCTAGGCGTCTGTCGGAGATTCTATTCAGAACATATGTACAACAATCGGCTAGGACCCACTGGCTAAACGCCTGTGGCAGAGTCTCGCTTTCTGTCAAGTCTACACTAGTAATAATGGTCGCGACTGTGTGCTTAAGCGATCCCGGGCGTATCCGATATGAGAGGTAAAGGTATATTGCTCGTCCCGCCCCCATCTAGGTGCGCGTTTTTCTAGATGATTCAGACCCTCTAAGCACCGACGATACTAGTACAAGAACTCTCCATGGTACCCTCATGCAGCTGTGACGTACCGTGTAAGTATCACTGTATAACTACGATTGGGTAATGCTCGTGTACCTGGTCTATAGTTTACGTATGGCACGTGCCAACCGCGCACCTTTTAGGATTCGAAAAGGCTGCGATCGCGGATGTGCTGGCTCGCTTCACAAAGAATAGGGCGCCGTATTAGCTCGCGGCCGGGTTGCGTTCCCGCTAAGTTACTCTATGCACGCTGGTATAAACTCTAGAGATATAAAATCATGAGCCCAGGGCGGGTTGTAAATATCAGCAACGTAACAATTGTGTGCGTTCCTTGGTATCTGCGCAATCGCGATTCTGGGTTACCGCGAGAGCCCCAGGTTCCGGTTTTACAAGTACAGGGCACAAGAGAGATACAGATGAGTGCACGCAAGATGCATTATCGCCATAACTGAAATGGAAGTTCCTTCCGCTAAAGTTGTACCGCACCGAGAGAAACCATTACTCCAAGGACGCTACAACGGGCTCATCTTCCCGTCAGCGGGTATGCAGTATACTTTACGCGGCCGTCCAACATCCCAGTCTATACCTAACCTTAGACATCGTCTTACAACAGCCGGTATCCCTGTGACCGCCCTACGTACGTTGTGGGTGGAAATCAAAAGACTAAATCAATGGATTTCGATGTCGGAGTGACTTTACTCCATGTGAATAAGACCGGACGAACGCCAACTCGAATTGTACCCGGCTCTCCTTTATCGACAGATGCGTCAATACACAGCGAGATCTATGCCTCGAGCAAATCCGGACACTTGACGTCTGCGATCGTAGAAGGACGGTTTTGTTAATCGTACAAACTACCTCCAATATAGCCCCTCGTACTGTTGACAGCGATACGGTGCTATGGCACTAATCTTCACTGGCGTTTATGGGTATGACAGCTTGGATCATTTACCCCTGACCACTCTTACATACGGAAGACAAATTCCAACCAAGCGCTGGATCTTCGCCAGTGACACCAGAATAGTAACCGGGACCACACATTCCTCAGCTGAAGGAAAAGGTAGCAAGTCACTGGAAGGCCTGGGCACAGGAACGATTGCCAAAATTCTTAAACGAGGCACGAGTAGTGATCCTAAGGCACGGAAACAGCGCGTGGCCGATCTGTCGTGCACCTTGTGGTACTTTTCTGGACGAAGAGCAACGTGTATTAACTCTTAACGCTCTTCTGACATGGCTCACAACGCAACAACGTACCGTTTAAGACTCACGGACACCTAACGCTTCCAACCCCCAAGTATTCACGATGCTCCCTCCGTCGTATACCACTCGTTAACTTGATAGGCTTGCTGAAAACAGTGCTCAGGCCCGGTCGGTCGCCTGTGGTAGCTACCTTACTTTACAGCGAATCTAGCGATAAGTTACGTTCAAACAAGACTGACTTTAACGCCGACGGAGAGTTAACCAATGGACCTTCCAGCGGCGCTGACTGTTAGGTGTGCAACTCCCCATGCCAATTAAAACCAATGGGCCTTACAAAATATGATCTGAATGTCCACATTAGTCTGGGAAGAGTCATATTGTGTCCATAGACCAACTTATCAATAGCCCCAGATACTCCCTTGCGGTATGGAGCTAGCATAGTTGCTTTAGTTATTTGAGAACGTGAACTTCCTATTTGTTGTTTACAATTCTAATCGTCTCCTATGCGAACACATAGAGTCCTGACCTAATTCGTTACGTGGCTTGGAAGGTTGCACAGGTCTATAAAGCCGTAGACAGTGGTCCAGATCGTCTTTGCGTTAATTCGGGACAAATCCCTTCCAGTTAACGTTACCACACGGGAGCTCCTACACGAAAATGCTCTTGGGTGTCCTATAACCTGTACATCTACCCAGGCTCGTCGCACCCCCAGGGAAAGGCCACATCTGCGAGGGCTCTGGCGGACCGTGAGTCTTTATTCTTACTCCAACTCCCCCGAAGTAGGCACTGAAGGCCGTTCGTGTGACAGTTCGACCCAGCAGCTCCGCCGTAAAATGCTACAGAATGAGTGACCCCCCCAGTACGGACACAATAGATTGTCCCTCGTCCACCGATATGCGACGCAATTATGCTCGAGCACAGTTTGCATACGATGCCTACAGATGGGTACCACTTGGGCCGGGGCGACTTTCGCCGGGATTGCCGAATATACGTAATGCCGTCATCGGGCCATTTAAAACGGGGAGACTGGGTGGGGAACAGTGAACCCTGAGGCTAGGCGCAAACATTGAGGGGATCGGACCGTTCAAGCCACGAATCCCACGGCGAAGATATCTAGGAACATGTAATCTGACGGATCTCTTACGAAAATCAGAGAACTGGTGCATCAGTGTCATGCCTTTTTAGACATCATATACATGTCTTAGCACATGGCAATTGGGTGCACAACATCCTTGAGTCGAATTCCCTACCGGTTAAGGGGACGTACAGAACACAACATAGGAAGTCTAGTTCGATGACGATCGAAAGCTCGTGCAACATTTACATTTCACGACGGACTCATTAACGTTGCCCCGGCGTGATATACGTCTGCCACTCGGCCCGTCGTACTAAGGTAATCCACTTGAAAGAGCAAGGTCTCTTGCAGGTGACAACACGTGCCTTTTCCGGTACTCAGGTGAATATATCTCGTCCAATGGGCCTCGCCGCAACTATCACCCTCGTTATCGACGCTAGGACGGTTGGGGATTTCTGCATTGGCTCGTAACTACCATATAAACTTTGCAAACCGGATTCCTTGCGTAGGGACCTTCATTGATATGGAAAGCTGCTCATCGTAGGGTATTTGCGCCGCGCAGTTTAAATGTCTTAATGCTGCGCCTCTAACGCTGTCATAAAACGTTTTTGTGAATAATAGAGACTAACTTCCGCTATTTCAAGTGAGTCTTGCTGGTCAGAAACAG . PASS SVTYPE=INS GT 0/1 0/1 \ No newline at end of file diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/adaptors/VariantHBaseQueryParser.java b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/adaptors/VariantHBaseQueryParser.java index 1de83e96382..9c838765146 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/adaptors/VariantHBaseQueryParser.java +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/adaptors/VariantHBaseQueryParser.java @@ -577,9 +577,12 @@ public Scan parseQuery(VariantQueryProjection selectElements, Query query, Query //// filters.addFilter(keyOnlyFilter); // scan.addColumn(genomeHelper.getColumnFamily(), VariantPhoenixHelper.VariantColumn.TYPE.bytes()); // } - if (selectElements.getFields().contains(VariantField.TYPE) || !scan.hasFamilies()) { - scan.addColumn(family, VariantColumn.TYPE.bytes()); - } + + // Alleles must always be included. + scan.addColumn(family, VariantColumn.ALLELES.bytes()); + // Because alleles column may be empty, we must still ensure that we get, at least, one result per row. + // Include "type" column, which is never empty. + scan.addColumn(family, VariantColumn.TYPE.bytes()); // if (!columnPrefixes.isEmpty()) { // MultipleColumnPrefixFilter columnPrefixFilter = new MultipleColumnPrefixFilter( diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/adaptors/phoenix/VariantPhoenixKeyFactory.java b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/adaptors/phoenix/VariantPhoenixKeyFactory.java index eedeeb3c9ed..1d78af0d860 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/adaptors/phoenix/VariantPhoenixKeyFactory.java +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/adaptors/phoenix/VariantPhoenixKeyFactory.java @@ -19,6 +19,8 @@ import htsjdk.variant.variantcontext.Allele; import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.StringUtils; +import org.apache.hadoop.hbase.HConstants; +import org.apache.hadoop.hbase.client.Result; import org.apache.hadoop.hbase.util.Bytes; import org.apache.hadoop.hbase.util.Pair; import org.apache.phoenix.query.QueryConstants; @@ -28,6 +30,7 @@ import org.opencb.biodata.models.variant.Variant; import org.opencb.biodata.models.variant.VariantBuilder; import org.opencb.biodata.models.variant.avro.*; +import org.opencb.opencga.storage.hadoop.variant.GenomeHelper; import java.sql.ResultSet; import java.sql.SQLException; @@ -43,12 +46,15 @@ */ public class VariantPhoenixKeyFactory { + public static final Integer UINT_SIZE = PUnsignedInt.INSTANCE.getByteSize(); protected static final String SV_ALTERNATE_SEPARATOR = "|"; protected static final String SV_ALTERNATE_SEPARATOR_SPLIT = "\\" + SV_ALTERNATE_SEPARATOR; public static final Comparator HBASE_KEY_CHROMOSOME_COMPARATOR = (c1, c2) -> Bytes.compareTo( VariantPhoenixKeyFactory.generateSimpleVariantRowKey(c1, 1, "N", "N"), VariantPhoenixKeyFactory.generateSimpleVariantRowKey(c2, 1, "N", "N")); + public static final String HASH_PREFIX = "#"; + public static final byte[] HASH_PREFIX_BYTES = Bytes.toBytes(HASH_PREFIX); public static byte[] generateVariantRowKey(String chrom, int position) { return generateSimpleVariantRowKey(chrom, position, "", ""); @@ -97,6 +103,12 @@ public static byte[] generateSimpleVariantRowKey(String chrom, int position, Str return generateVariantRowKey(chrom, position, null, ref, alt, null); } + public static boolean mightHashAlleles(Variant variant) { + String alt = buildSymbolicAlternate(variant.getReference(), variant.getAlternate(), variant.getEnd(), variant.getSv()); + int size = getSize(variant.getChromosome(), variant.getReference(), variant.getAlternate()); + return size > HConstants.MAX_ROW_LENGTH; + } + /** * Generates a Row key based on Chromosome, start, end (optional), ref and alt.
*
    @@ -114,16 +126,16 @@ public static byte[] generateSimpleVariantRowKey(String chrom, int position, Str */ public static byte[] generateVariantRowKey(String chrom, int start, Integer end, String ref, String alt, StructuralVariation sv) { chrom = Region.normalizeChromosome(chrom); - int size = PVarchar.INSTANCE.estimateByteSizeFromLength(chrom.length()) - + QueryConstants.SEPARATOR_BYTE_ARRAY.length - + PUnsignedInt.INSTANCE.getByteSize() - + PVarchar.INSTANCE.estimateByteSizeFromLength(ref.length()); alt = buildSymbolicAlternate(ref, alt, end, sv); - if (!alt.isEmpty()) { - size += QueryConstants.SEPARATOR_BYTE_ARRAY.length - + PVarchar.INSTANCE.estimateByteSizeFromLength(alt.length()); + int size = getSize(chrom, ref, alt); + + if (size > HConstants.MAX_ROW_LENGTH) { + // This is a problem. The row key is too long. + // Use hashCode for reference/alternate/SV fields + ref = hashAllele(ref); + alt = hashAllele(alt); + size = getSize(chrom, ref, alt); } - byte[] rk = new byte[size]; int offset = 0; @@ -143,6 +155,26 @@ public static byte[] generateVariantRowKey(String chrom, int start, Integer end, return rk; } + private static int getSize(String chrom, String ref, String alt) { + int size = PVarchar.INSTANCE.estimateByteSizeFromLength(chrom.length()) + + QueryConstants.SEPARATOR_BYTE_ARRAY.length + + PUnsignedInt.INSTANCE.getByteSize() + + PVarchar.INSTANCE.estimateByteSizeFromLength(ref.length()); + if (!alt.isEmpty()) { + size += QueryConstants.SEPARATOR_BYTE_ARRAY.length + + PVarchar.INSTANCE.estimateByteSizeFromLength(alt.length()); + } + return size; + } + + public static String hashAllele(String ref) { + return HASH_PREFIX + Integer.toString(ref.hashCode()); + } + + public static String buildAlleles(Variant v) { + return v.getReference() + SV_ALTERNATE_SEPARATOR + buildSymbolicAlternate(v); + } + public static String buildSymbolicAlternate(Variant v) { return buildSymbolicAlternate(v.getReference(), v.getAlternate(), v.getEnd(), v.getSv()); } @@ -215,6 +247,24 @@ public static String extractChrFromVariantRowKey(byte[] variantRowKey, int offse return (String) PVarchar.INSTANCE.toObject(variantRowKey, offset, chrPosSeparator, PVarchar.INSTANCE); } + public static Variant extractVariantFromResult(Result result) { + byte[] variantRowKey = result.getRow(); + + int chrPosSeparator = ArrayUtils.indexOf(variantRowKey, (byte) 0); + int referenceOffset = chrPosSeparator + 1 + UINT_SIZE; + if (Bytes.equals(variantRowKey, referenceOffset, HASH_PREFIX_BYTES.length, HASH_PREFIX_BYTES, 0, HASH_PREFIX_BYTES.length)) { + // The reference and alternate are hashed. + // The type and alleles are stored in the result + byte[] type = result.getValue(GenomeHelper.COLUMN_FAMILY_BYTES, + VariantPhoenixSchema.VariantColumn.TYPE.bytes()); + byte[] alleles = result.getValue(GenomeHelper.COLUMN_FAMILY_BYTES, + VariantPhoenixSchema.VariantColumn.ALLELES.bytes()); + return extractVariantFromVariantRowKey(variantRowKey, type, alleles); + } else { + return extractVariantFromVariantRowKey(variantRowKey, null, null); + } + } + public static Variant extractVariantFromResultSet(ResultSet resultSet) { String chromosome = null; Integer start = null; @@ -226,9 +276,10 @@ public static Variant extractVariantFromResultSet(ResultSet resultSet) { reference = resultSet.getString(VariantPhoenixSchema.VariantColumn.REFERENCE.column()); alternate = resultSet.getString(VariantPhoenixSchema.VariantColumn.ALTERNATE.column()); + String alleles = resultSet.getString(VariantPhoenixSchema.VariantColumn.ALLELES.column()); String type = resultSet.getString(VariantPhoenixSchema.VariantColumn.TYPE.column()); - return buildVariant(chromosome, start, reference, alternate, type); + return buildVariant(chromosome, start, reference, alternate, type, alleles); } catch (RuntimeException | SQLException e) { throw new IllegalStateException("Fail to parse variant: " + chromosome + ':' + start @@ -237,13 +288,12 @@ public static Variant extractVariantFromResultSet(ResultSet resultSet) { } } - public static Variant extractVariantFromVariantRowKey(byte[] variantRowKey) { + public static Variant extractVariantFromVariantRowKey(byte[] variantRowKey, byte[] type, byte[] alleles) { int chrPosSeparator = ArrayUtils.indexOf(variantRowKey, (byte) 0); String chromosome = (String) PVarchar.INSTANCE.toObject(variantRowKey, 0, chrPosSeparator, PVarchar.INSTANCE); - Integer intSize = PUnsignedInt.INSTANCE.getByteSize(); - int position = (Integer) PUnsignedInt.INSTANCE.toObject(variantRowKey, chrPosSeparator + 1, intSize, PUnsignedInt.INSTANCE); - int referenceOffset = chrPosSeparator + 1 + intSize; + int position = (Integer) PUnsignedInt.INSTANCE.toObject(variantRowKey, chrPosSeparator + 1, UINT_SIZE, PUnsignedInt.INSTANCE); + int referenceOffset = chrPosSeparator + 1 + UINT_SIZE; int refAltSeparator = ArrayUtils.indexOf(variantRowKey, (byte) 0, referenceOffset); String reference; String alternate; @@ -257,8 +307,16 @@ public static Variant extractVariantFromVariantRowKey(byte[] variantRowKey) { alternate = (String) PVarchar.INSTANCE.toObject(variantRowKey, refAltSeparator + 1, variantRowKey.length - (refAltSeparator + 1), PVarchar.INSTANCE); } + String typeStr = null; + String alleleStr = null; + if (type != null) { + typeStr = (String) PVarchar.INSTANCE.toObject(type); + } + if (alleles != null) { + alleleStr = (String) PVarchar.INSTANCE.toObject(alleles); + } try { - return buildVariant(chromosome, position, reference, alternate, null); + return buildVariant(chromosome, position, reference, alternate, typeStr, alleleStr); } catch (RuntimeException e) { throw new IllegalStateException("Fail to parse variant: " + chromosome + ':' + position @@ -268,7 +326,17 @@ public static Variant extractVariantFromVariantRowKey(byte[] variantRowKey) { } } - public static Variant buildVariant(String chromosome, int start, String reference, String alternate, String type) { + public static Variant buildVariant(String chromosome, int start, String reference, String alternate, String type, String alleles) { + if ((reference != null && reference.startsWith(HASH_PREFIX)) || (alternate != null && alternate.startsWith(HASH_PREFIX))) { + if (StringUtils.isNotEmpty(alleles)) { + int i1 = alleles.indexOf(SV_ALTERNATE_SEPARATOR); + reference = alleles.substring(0, i1); + alternate = alleles.substring(i1 + SV_ALTERNATE_SEPARATOR.length()); + } else { + throw new IllegalStateException("Reference and alternate are hashed, but alleles is empty!" + + " '" + chromosome + "' '" + start + "' '" + reference + "' '" + alternate + "'"); + } + } if (alternate != null && alternate.length() > 5 && alternate.contains(SV_ALTERNATE_SEPARATOR)) { Integer end = null; diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/adaptors/phoenix/VariantPhoenixSchema.java b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/adaptors/phoenix/VariantPhoenixSchema.java index 1d408da09b4..eb627dcaeda 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/adaptors/phoenix/VariantPhoenixSchema.java +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/adaptors/phoenix/VariantPhoenixSchema.java @@ -105,6 +105,7 @@ public enum VariantColumn implements Column { CI_END_R("CI_END_R", PUnsignedInt.INSTANCE), TYPE("TYPE", PVarchar.INSTANCE), + ALLELES("ALLELES", PVarchar.INSTANCE), ANNOTATION_ID(ANNOTATION_PREFIX + "ID", PInteger.INSTANCE), diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/adaptors/phoenix/VariantSqlQueryParser.java b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/adaptors/phoenix/VariantSqlQueryParser.java index 7cc9dd77bf4..6a7d9fe5518 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/adaptors/phoenix/VariantSqlQueryParser.java +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/adaptors/phoenix/VariantSqlQueryParser.java @@ -221,7 +221,8 @@ protected StringBuilder appendProjectedColumns(StringBuilder sb, VariantQueryPro .append(VariantColumn.POSITION).append(',') .append(VariantColumn.REFERENCE).append(',') .append(VariantColumn.ALTERNATE).append(',') - .append(VariantColumn.TYPE); + .append(VariantColumn.TYPE).append(',') + .append(VariantColumn.ALLELES); for (VariantQueryProjection.StudyVariantQueryProjection study : projection.getStudies().values()) { int studyId = study.getId(); @@ -599,10 +600,17 @@ private String getVariantFilter(List variants) { Iterator iterator = variants.iterator(); while (iterator.hasNext()) { Variant variant = iterator.next(); + + String reference = variant.getReference(); + String alternate = VariantPhoenixKeyFactory.buildSymbolicAlternate(variant); + if (VariantPhoenixKeyFactory.mightHashAlleles(variant)) { + reference = VariantPhoenixKeyFactory.hashAllele(reference); + alternate = VariantPhoenixKeyFactory.hashAllele(alternate); + } sb.append("('").append(checkStringValue(variant.getChromosome())).append("', ") .append(variant.getStart()).append(", ") - .append('\'').append(checkStringValue(variant.getReference())).append("', ") - .append('\'').append(checkStringValue(VariantPhoenixKeyFactory.buildSymbolicAlternate(variant))).append("') "); + .append('\'').append(checkStringValue(reference)).append("', ") + .append('\'').append(checkStringValue(alternate)).append("') "); if (iterator.hasNext()) { sb.append(','); } @@ -709,9 +717,9 @@ protected List getOtherFilters(ParsedVariantQuery variantQuery, QueryOpt protected void addVariantFilters(ParsedVariantQuery variantQuery, QueryOptions options, List filters) { Query query = variantQuery.getQuery(); - addQueryFilter(query, REFERENCE, VariantColumn.REFERENCE, filters); + addQueryFilter(query, REFERENCE, VariantColumn.REFERENCE, filters, VariantSqlQueryParser::hashAlleles); - addQueryFilter(query, ALTERNATE, VariantColumn.ALTERNATE, filters); + addQueryFilter(query, ALTERNATE, VariantColumn.ALTERNATE, filters, VariantSqlQueryParser::hashAlleles); addQueryFilter(query, TYPE, VariantColumn.TYPE, filters); @@ -1081,6 +1089,16 @@ protected void addVariantFilters(ParsedVariantQuery variantQuery, QueryOptions o } } + private static List hashAlleles(String r) { + String[] split = r.split(","); + List list = new ArrayList<>(split.length * 2); + for (String s : split) { + list.add(s); + list.add(VariantPhoenixKeyFactory.hashAllele(s)); + } + return list; + } + private void addFileFilterFieldFilter(QueryOperation filtersOperation, List filterValues, StringBuilder sb, Pair fileIdPair) { sb.append(" ( "); diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/adaptors/sample/HBaseVariantSampleDataManager.java b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/adaptors/sample/HBaseVariantSampleDataManager.java index a96c57e9a45..6f426b59c43 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/adaptors/sample/HBaseVariantSampleDataManager.java +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/adaptors/sample/HBaseVariantSampleDataManager.java @@ -138,6 +138,8 @@ protected DataResult getSampleData(Variant variant, String study, Query List stats = new LinkedList<>(); dbAdaptor.getHBaseManager().act(dbAdaptor.getVariantTable(), table -> { Get get = new Get(VariantPhoenixKeyFactory.generateVariantRowKey(variant)); + get.addColumn(GenomeHelper.COLUMN_FAMILY_BYTES, VariantPhoenixSchema.VariantColumn.TYPE.bytes()); + get.addColumn(GenomeHelper.COLUMN_FAMILY_BYTES, VariantPhoenixSchema.VariantColumn.ALLELES.bytes()); // Add file columns for (Integer fileId : fileIdsFromSampleIds) { get.addColumn(GenomeHelper.COLUMN_FAMILY_BYTES, VariantPhoenixSchema.buildFileColumnKey(studyId, fileId)); diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/annotation/pending/AnnotationPendingVariantsDescriptor.java b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/annotation/pending/AnnotationPendingVariantsDescriptor.java index c5ba3d73e83..c606a42043f 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/annotation/pending/AnnotationPendingVariantsDescriptor.java +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/annotation/pending/AnnotationPendingVariantsDescriptor.java @@ -1,6 +1,7 @@ package org.opencb.opencga.storage.hadoop.variant.annotation.pending; import org.apache.hadoop.hbase.Cell; +import org.apache.hadoop.hbase.CellUtil; import org.apache.hadoop.hbase.client.*; import org.apache.hadoop.hbase.io.compress.Compression; import org.apache.hadoop.hbase.util.Bytes; @@ -16,8 +17,7 @@ import java.io.IOException; import java.util.function.Function; -import static org.opencb.opencga.storage.hadoop.variant.adaptors.phoenix.VariantPhoenixSchema.VariantColumn.SO; -import static org.opencb.opencga.storage.hadoop.variant.adaptors.phoenix.VariantPhoenixSchema.VariantColumn.TYPE; +import static org.opencb.opencga.storage.hadoop.variant.adaptors.phoenix.VariantPhoenixSchema.VariantColumn.*; public class AnnotationPendingVariantsDescriptor implements PendingVariantsDescriptor { @@ -50,6 +50,7 @@ public boolean createTableIfNeeded(String tableName, HBaseManager hBaseManager) public Scan configureScan(Scan scan, VariantStorageMetadataManager metadataManager) { scan.addColumn(GenomeHelper.COLUMN_FAMILY_BYTES, TYPE.bytes()); + scan.addColumn(GenomeHelper.COLUMN_FAMILY_BYTES, ALLELES.bytes()); scan.addColumn(GenomeHelper.COLUMN_FAMILY_BYTES, SO.bytes()); return scan; } @@ -57,9 +58,22 @@ public Scan configureScan(Scan scan, VariantStorageMetadataManager metadataManag public Function getPendingEvaluatorMapper(VariantStorageMetadataManager metadataManager, boolean overwrite) { return value -> { + byte[] alleles = null; if (overwrite || isPending(value)) { + for (Cell cell : value.rawCells()) { + if (cell.getValueLength() > 0) { + if (Bytes.equals( + cell.getQualifierArray(), cell.getQualifierOffset(), cell.getQualifierLength(), + ALLELES.bytes(), 0, ALLELES.bytes().length)) { + alleles = CellUtil.cloneValue(cell); + } + } + } Put put = new Put(value.getRow()); put.addColumn(FAMILY, COLUMN, VALUE); + if (alleles != null) { + put.addColumn(FAMILY, ALLELES.bytes(), alleles); + } return put; } else { return new Delete(value.getRow()); diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/converters/HBaseToVariantConverter.java b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/converters/HBaseToVariantConverter.java index 026a6a5e122..4bfcb0011e1 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/converters/HBaseToVariantConverter.java +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/converters/HBaseToVariantConverter.java @@ -48,8 +48,7 @@ import java.util.stream.Collectors; import static org.opencb.opencga.storage.core.variant.VariantStorageOptions.SEARCH_INDEX_LAST_TIMESTAMP; -import static org.opencb.opencga.storage.hadoop.variant.adaptors.phoenix.VariantPhoenixKeyFactory.extractVariantFromResultSet; -import static org.opencb.opencga.storage.hadoop.variant.adaptors.phoenix.VariantPhoenixKeyFactory.extractVariantFromVariantRowKey; +import static org.opencb.opencga.storage.hadoop.variant.adaptors.phoenix.VariantPhoenixKeyFactory.*; /** * Created on 20/11/15. @@ -210,7 +209,7 @@ private static class ResultToVariantConverter extends HBaseToVariantConverter 0) { diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/converters/VariantRow.java b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/converters/VariantRow.java index 4b0b6ef9584..f3700d24d15 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/converters/VariantRow.java +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/converters/VariantRow.java @@ -66,7 +66,7 @@ public Variant getVariant() { if (result != null) { byte[] row = result.getRow(); Objects.requireNonNull(row, "Empty result. Missing variant rowkey."); - variant = VariantPhoenixKeyFactory.extractVariantFromVariantRowKey(row); + variant = VariantPhoenixKeyFactory.extractVariantFromResult(result); } else { variant = VariantPhoenixKeyFactory.extractVariantFromResultSet(resultSet); } @@ -136,6 +136,10 @@ protected void walk(VariantRowWalker walker, boolean file, boolean sample, boole walker.fillMissing(studyId, resultSet.getInt(i)); } else if (annotation && columnName.equals(VariantColumn.FULL_ANNOTATION.column())) { walker.variantAnnotation(new BytesVariantAnnotationColumn(bytes)); + } else if (columnName.equals(VariantColumn.TYPE.column())) { + walker.type(VariantType.valueOf(Bytes.toString(bytes))); + } else if (columnName.equals(VariantColumn.ALLELES.column())) { + walker.alleles(Bytes.toString(bytes)); } } } catch (SQLException e) { @@ -164,6 +168,8 @@ protected void walk(VariantRowWalker walker, boolean file, boolean sample, boole walker.variantAnnotation(new BytesVariantAnnotationColumn(cell)); } else if (columnName.equals(VariantColumn.TYPE.column())) { walker.type(VariantType.valueOf(Bytes.toString(cell.getValueArray(), cell.getValueOffset(), cell.getValueLength()))); + } else if (columnName.equals(VariantColumn.ALLELES.column())) { + walker.alleles(Bytes.toString(cell.getValueArray(), cell.getValueOffset(), cell.getValueLength())); } } } @@ -177,6 +183,9 @@ protected void variant(Variant variant) { protected void type(VariantType type) { } + protected void alleles(String alleles) { + } + protected void study(int studyId) { } @@ -202,6 +211,7 @@ protected void variantAnnotation(VariantAnnotationColumn column) { public class VariantRowWalkerBuilder extends VariantRowWalker { private IntConsumer studyConsumer = r -> { }; + private Consumer allelesConsumer = r -> { }; private Consumer fileConsumer = r -> { }; private boolean hasFileConsumer = false; private Consumer sampleConsumer = r -> { }; @@ -229,6 +239,11 @@ protected void study(int studyId) { studyConsumer.accept(studyId); } + @Override + protected void alleles(String alleles) { + allelesConsumer.accept(alleles); + } + @Override protected void file(FileColumn fileColumn) { fileConsumer.accept(fileColumn); @@ -274,6 +289,11 @@ public VariantRowWalkerBuilder onStudy(IntConsumer consumer) { return this; } + public VariantRowWalkerBuilder onAlleles(Consumer consumer) { + allelesConsumer = consumer; + return this; + } + public VariantRowWalkerBuilder onFile(Consumer consumer) { fileConsumer = consumer; hasFileConsumer = true; diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/converters/study/StudyEntryToHBaseConverter.java b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/converters/study/StudyEntryToHBaseConverter.java index e3188e15716..4a4bafa1be8 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/converters/study/StudyEntryToHBaseConverter.java +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/converters/study/StudyEntryToHBaseConverter.java @@ -119,6 +119,7 @@ public Put convert(Variant variant) { add(put, VariantPhoenixSchema.VariantColumn.CI_END_R, Math.max(0, variant.getSv().getCiEndRight())); } } + add(put, VariantPhoenixSchema.VariantColumn.ALLELES, VariantPhoenixKeyFactory.buildAlleles(variant)); add(put, studyColumn, 0); if (releaseColumn != null) { add(put, releaseColumn, true); diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/gaps/PrepareFillMissingMapper.java b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/gaps/PrepareFillMissingMapper.java index 080a1a66a7a..10feadf2cc8 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/gaps/PrepareFillMissingMapper.java +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/gaps/PrepareFillMissingMapper.java @@ -57,7 +57,7 @@ protected void setup(Context context) throws IOException, InterruptedException { @Override protected void map(ImmutableBytesWritable key, Result value, Context context) throws IOException, InterruptedException { - Variant variant = VariantPhoenixKeyFactory.extractVariantFromVariantRowKey(value.getRow()); + Variant variant = VariantPhoenixKeyFactory.extractVariantFromResult(value); byte[] column = FillMissingFromArchiveTask.getArchiveVariantColumn(variant); long sliceId = rowKeyFactory.getSliceId(variant.getStart()); String chromosome = variant.getChromosome(); diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/index/annotation/mr/VariantTableSampleIndexOrderMapper.java b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/index/annotation/mr/VariantTableSampleIndexOrderMapper.java index 0d1e45f40be..cbf0952a876 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/index/annotation/mr/VariantTableSampleIndexOrderMapper.java +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/index/annotation/mr/VariantTableSampleIndexOrderMapper.java @@ -52,8 +52,8 @@ public void run(Context context) throws IOException, InterruptedException { // Sort buffer if (buffer.size() > 1) { buffer.sort((o1, o2) -> { - Variant v1 = VariantPhoenixKeyFactory.extractVariantFromVariantRowKey(o1.getSecond().getRow()); - Variant v2 = VariantPhoenixKeyFactory.extractVariantFromVariantRowKey(o2.getSecond().getRow()); + Variant v1 = VariantPhoenixKeyFactory.extractVariantFromResult(o1.getSecond()); + Variant v2 = VariantPhoenixKeyFactory.extractVariantFromResult(o2.getSecond()); return SampleIndexSchema.INTRA_CHROMOSOME_VARIANT_COMPARATOR.compare(v1, v2); }); } diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/index/sample/AlleleCodec.java b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/index/sample/AlleleCodec.java index 62f2443a947..587c8fbfac1 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/index/sample/AlleleCodec.java +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/index/sample/AlleleCodec.java @@ -26,8 +26,8 @@ public static boolean validAllele(String allele) { } public static byte encode(String ref, String alt) { - byte refCode = encode(ref); - byte altCode = encode(alt); + byte refCode = encode(ref.charAt(0)); + byte altCode = encode(alt.charAt(0)); return join(refCode, altCode); } @@ -38,8 +38,8 @@ public static String[] decode(byte refAltCode) { }; } - public static byte encode(String allele) { - switch (allele.charAt(0)) { + public static byte encode(char allele) { + switch (allele) { case 'A': return 0b00; // 0 case 'C': diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/index/sample/SampleIndexVariantBiConverter.java b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/index/sample/SampleIndexVariantBiConverter.java index d8961251205..83e9dec3900 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/index/sample/SampleIndexVariantBiConverter.java +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/index/sample/SampleIndexVariantBiConverter.java @@ -645,7 +645,7 @@ private Variant toVariantEncodedAlleles(String chromosome, int batchStart, byte[ String[] refAlt = AlleleCodec.decode(bytes[offset]); int start = batchStart + (read24bitInteger(bytes, offset) & 0x0F_FF_FF); - return VariantPhoenixKeyFactory.buildVariant(chromosome, start, refAlt[0], refAlt[1], null); + return VariantPhoenixKeyFactory.buildVariant(chromosome, start, refAlt[0], refAlt[1], null, null); } private Variant toVariant(String chromosome, int batchStart, byte[] bytes, int offset, int referenceLength, int alternateLength) { @@ -655,7 +655,7 @@ private Variant toVariant(String chromosome, int batchStart, byte[] bytes, int o offset += referenceLength + SEPARATOR_LENGTH; // add reference, and separator String alternate = readString(bytes, offset, alternateLength); - return VariantPhoenixKeyFactory.buildVariant(chromosome, start, reference, alternate, null); + return VariantPhoenixKeyFactory.buildVariant(chromosome, start, reference, alternate, null, null); } private int readNextSeparator(byte[] bytes, int offset) { diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/mr/SampleIndexTableRecordReader.java b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/mr/SampleIndexTableRecordReader.java index 2efd1115846..9790f5b99b1 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/mr/SampleIndexTableRecordReader.java +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/mr/SampleIndexTableRecordReader.java @@ -7,6 +7,7 @@ import org.apache.hadoop.hbase.client.Table; import org.apache.hadoop.hbase.io.ImmutableBytesWritable; import org.apache.hadoop.hbase.mapreduce.TableRecordReader; +import org.apache.hadoop.hbase.util.Pair; import org.apache.hadoop.mapreduce.InputSplit; import org.apache.hadoop.mapreduce.TaskAttemptContext; import org.opencb.biodata.models.core.Region; @@ -186,9 +187,9 @@ public void initialize(InputSplit inputsplit, TaskAttemptContext context) throws startChr = null; start = 0; } else { - Variant startVariant = VariantPhoenixKeyFactory.extractVariantFromVariantRowKey(firstRow); - startChr = startVariant.getChromosome(); - start = startVariant.getStart(); + Pair startLocus = VariantPhoenixKeyFactory.extractChrPosFromVariantRowKey(firstRow); + startChr = startLocus.getFirst(); + start = startLocus.getSecond(); } String stopChr; Integer end; @@ -197,9 +198,9 @@ public void initialize(InputSplit inputsplit, TaskAttemptContext context) throws stopChr = null; end = Integer.MAX_VALUE; } else { - Variant stopVariant = VariantPhoenixKeyFactory.extractVariantFromVariantRowKey(lastRow); - stopChr = stopVariant.getChromosome(); - end = stopVariant.getStart(); + Pair stopLocus = VariantPhoenixKeyFactory.extractChrPosFromVariantRowKey(firstRow); + stopChr = stopLocus.getFirst(); + end = stopLocus.getSecond(); } List regions = new ArrayList<>(); diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/pending/PendingVariantsDescriptor.java b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/pending/PendingVariantsDescriptor.java index 152c0a86c3c..972f1aeecfe 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/pending/PendingVariantsDescriptor.java +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/pending/PendingVariantsDescriptor.java @@ -35,6 +35,13 @@ default boolean createTableIfNeeded(HBaseVariantTableNameGenerator generator, HB boolean createTableIfNeeded(String tableName, HBaseManager hBaseManager) throws IOException; + /** + * Configure the scan to read from the variants table. + * + * @param scan Scan to configure + * @param metadataManager Metadata manager + * @return The same scan object + */ Scan configureScan(Scan scan, VariantStorageMetadataManager metadataManager); Function getPendingEvaluatorMapper(VariantStorageMetadataManager metadataManager, boolean overwrite); diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/pending/PendingVariantsReader.java b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/pending/PendingVariantsReader.java index 3a58ebdb1bd..54d93c5c6ba 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/pending/PendingVariantsReader.java +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/pending/PendingVariantsReader.java @@ -52,7 +52,7 @@ public boolean pre() { protected List convert(List results) { List variants = new ArrayList<>(results.size()); for (Result result : results) { - variants.add(VariantPhoenixKeyFactory.extractVariantFromVariantRowKey(result.getRow())); + variants.add(VariantPhoenixKeyFactory.extractVariantFromResult(result)); } return variants; } diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/prune/VariantPruneDriver.java b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/prune/VariantPruneDriver.java index a2ff5f08b4a..cf404e1daf5 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/prune/VariantPruneDriver.java +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/prune/VariantPruneDriver.java @@ -23,7 +23,6 @@ import org.opencb.opencga.storage.core.metadata.models.VariantScoreMetadata; import org.opencb.opencga.storage.hadoop.variant.AbstractVariantsTableDriver; import org.opencb.opencga.storage.hadoop.variant.adaptors.phoenix.PhoenixHelper; -import org.opencb.opencga.storage.hadoop.variant.adaptors.phoenix.VariantPhoenixKeyFactory; import org.opencb.opencga.storage.hadoop.variant.adaptors.phoenix.VariantPhoenixSchema; import org.opencb.opencga.storage.hadoop.variant.converters.VariantRow; import org.opencb.opencga.storage.hadoop.variant.mr.VariantMapReduceUtil; @@ -37,6 +36,7 @@ import java.lang.invoke.MethodHandles; import java.nio.charset.StandardCharsets; import java.util.*; +import java.util.concurrent.atomic.AtomicReference; import java.util.stream.Collectors; import static org.opencb.biodata.models.variant.StudyEntry.DEFAULT_COHORT; @@ -45,6 +45,7 @@ public class VariantPruneDriver extends AbstractVariantsTableDriver { private Logger logger = LoggerFactory.getLogger(VariantPruneManager.class); + public static final String ATTRIBUTE_DELETION_VARIANT = "d_variant"; public static final String ATTRIBUTE_DELETION_STUDIES = "d_studies"; public static final String ATTRIBUTE_DELETION_TYPE = "d_type"; public static final byte[] ATTRIBUTE_DELETION_TYPE_FULL = Bytes.toBytes(VariantPruneReportRecord.Type.FULL.toString()); @@ -210,7 +211,7 @@ protected void map(ImmutableBytesWritable key, Result value, Context context) List emptyStudies = new ArrayList<>(); List studies = new ArrayList<>(); List studiesWithStats = new ArrayList<>(); - + AtomicReference alleles = new AtomicReference<>(); Variant variant = variantRow.walker() .onStudy(studies::add) .onCohortStats(c -> { @@ -220,6 +221,7 @@ protected void map(ImmutableBytesWritable key, Result value, Context context) emptyStudies.add(c.getStudyId()); } }) + .onAlleles(alleles::set) .walk(); for (Integer studyWithStats : studiesWithStats) { @@ -253,13 +255,18 @@ protected void map(ImmutableBytesWritable key, Result value, Context context) // Drop variant && add to deleted variants list context.getCounter(COUNTER_GROUP_NAME, "variants_deleted").increment(1); - context.write(pendingDeletionVariantsTable, - new Put(value.getRow()).addColumn(COLUMN_FAMILY_BYTES, COLUMN, VALUE)); + Put put = new Put(value.getRow()) + .addColumn(COLUMN_FAMILY_BYTES, COLUMN, VALUE); + if (alleles.get() != null) { + put.addColumn(COLUMN_FAMILY_BYTES, VariantPhoenixSchema.VariantColumn.ALLELES.bytes(), Bytes.toBytes(alleles.get())); + } + context.write(pendingDeletionVariantsTable, put); context.write(pendingAnnotationVariantsTable, new Delete(value.getRow())); Delete delete = new Delete(value.getRow()); delete.addFamily(COLUMN_FAMILY_BYTES); + delete.setAttribute(ATTRIBUTE_DELETION_VARIANT, Bytes.toBytes(variant.toString())); delete.setAttribute(ATTRIBUTE_DELETION_TYPE, ATTRIBUTE_DELETION_TYPE_FULL); delete.setAttribute(ATTRIBUTE_DELETION_STUDIES, Bytes.toBytes(emptyStudies.stream() @@ -285,12 +292,16 @@ protected void map(ImmutableBytesWritable key, Result value, Context context) // This block is here to prevent accidental "full row" deletes. throw new IllegalStateException("Unexpected empty delete at partial variant prune in variant " + variant); } + delete.setAttribute(ATTRIBUTE_DELETION_VARIANT, Bytes.toBytes(variant.toString())); delete.setAttribute(ATTRIBUTE_DELETION_TYPE, ATTRIBUTE_DELETION_TYPE_PARTIAL); delete.setAttribute(ATTRIBUTE_DELETION_STUDIES, Bytes.toBytes(emptyStudies.stream().map(Object::toString).collect(Collectors.joining(",")))); Put updateSecondaryIndexColumns = new Put(value.getRow()); - + if (alleles.get() != null) { + updateSecondaryIndexColumns.addColumn(COLUMN_FAMILY_BYTES, + VariantPhoenixSchema.VariantColumn.ALLELES.bytes(), Bytes.toBytes(alleles.get())); + } HadoopVariantSearchIndexUtils.addNotSyncStatus(updateSecondaryIndexColumns); context.write(variantsTable, delete); @@ -360,8 +371,7 @@ public ReportRecordWriter(DataOutputStream out, ImmutableBytesWritable variantsT public synchronized void write(ImmutableBytesWritable key, Mutation mutation) throws IOException { if (mutation instanceof Delete && key.equals(variantsTable)) { - Variant variant = VariantPhoenixKeyFactory.extractVariantFromVariantRowKey(mutation.getRow()); - out.write(variant.toString().getBytes(StandardCharsets.UTF_8)); + out.write(mutation.getAttribute(ATTRIBUTE_DELETION_VARIANT)); out.write(SEPARATOR); out.write(mutation.getAttribute(ATTRIBUTE_DELETION_TYPE)); out.write(SEPARATOR); diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/prune/VariantPruneManager.java b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/prune/VariantPruneManager.java index 93d6801d448..43299e6e503 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/prune/VariantPruneManager.java +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/prune/VariantPruneManager.java @@ -205,7 +205,7 @@ private void checkReportedVariants(Path report, long count) throws IOException, Result[] get = table.get(gets); for (int i = 0; i < get.length; i++) { Result result = get[i]; - Variant variant = VariantPhoenixKeyFactory.extractVariantFromVariantRowKey(result.getRow()); + Variant variant = VariantPhoenixKeyFactory.extractVariantFromResult(result); VariantPruneReportRecord record = batch.get(i); if (!variant.sameGenomicVariant(record.getVariant())) { throw new IllegalStateException("Error checking report! Expected " diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/search/SecondaryIndexPendingVariantsDescriptor.java b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/search/SecondaryIndexPendingVariantsDescriptor.java index 604611ca93c..0f54668b988 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/search/SecondaryIndexPendingVariantsDescriptor.java +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/search/SecondaryIndexPendingVariantsDescriptor.java @@ -54,6 +54,7 @@ public boolean createTableIfNeeded(String tableName, HBaseManager hBaseManager) @Override public Scan configureScan(Scan scan, VariantStorageMetadataManager metadataManager) { scan.addColumn(GenomeHelper.COLUMN_FAMILY_BYTES, TYPE.bytes()); + scan.addColumn(GenomeHelper.COLUMN_FAMILY_BYTES, ALLELES.bytes()); scan.addColumn(GenomeHelper.COLUMN_FAMILY_BYTES, FULL_ANNOTATION.bytes()); scan.addColumn(GenomeHelper.COLUMN_FAMILY_BYTES, ANNOTATION_ID.bytes()); scan.addColumn(GenomeHelper.COLUMN_FAMILY_BYTES, INDEX_NOT_SYNC.bytes()); diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/stats/CheckVariantStatsDriver.java b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/stats/CheckVariantStatsDriver.java index 091a93eef54..c39ade7a754 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/stats/CheckVariantStatsDriver.java +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/stats/CheckVariantStatsDriver.java @@ -369,7 +369,7 @@ protected void setup(Context context) throws IOException, InterruptedException { @Override protected void map(ImmutableBytesWritable key, Result value, Context context) throws IOException, InterruptedException { - Variant variant = VariantPhoenixKeyFactory.extractVariantFromVariantRowKey(value.getRow()); + Variant variant = VariantPhoenixKeyFactory.extractVariantFromResult(value); VariantType type = variant.getType(); int chromosomeIdx = FileStatsWritable.getChromosomeIdx(variant.getChromosome()); for (Cell cell : value.rawCells()) { diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/stats/VariantStatsFromResultMapper.java b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/stats/VariantStatsFromResultMapper.java index 28b0115a326..7bc90517688 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/stats/VariantStatsFromResultMapper.java +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/stats/VariantStatsFromResultMapper.java @@ -165,7 +165,7 @@ public void run(Context context) throws IOException, InterruptedException { // } protected void map(ImmutableBytesWritable key, Result value, Context context) throws IOException, InterruptedException { - Variant variant = VariantPhoenixKeyFactory.extractVariantFromVariantRowKey(value.getRow()); + Variant variant = VariantPhoenixKeyFactory.extractVariantFromResult(value); VariantStatsWrapper wrapper = new VariantStatsWrapper(variant, new ArrayList<>(calculators.size())); calculators.forEach((cohort, calculator) -> { diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/test/java/org/opencb/opencga/storage/hadoop/variant/HadoopVariantStorageEngineSVTest.java b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/test/java/org/opencb/opencga/storage/hadoop/variant/HadoopVariantStorageEngineSVTest.java index 09bbce14acd..e46e1bb6782 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/test/java/org/opencb/opencga/storage/hadoop/variant/HadoopVariantStorageEngineSVTest.java +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/test/java/org/opencb/opencga/storage/hadoop/variant/HadoopVariantStorageEngineSVTest.java @@ -4,19 +4,19 @@ import org.junit.ClassRule; import org.junit.Test; import org.junit.experimental.categories.Category; +import org.opencb.biodata.models.variant.StudyEntry; import org.opencb.biodata.models.variant.Variant; -import org.opencb.commons.datastore.core.Query; import org.opencb.commons.datastore.core.QueryOptions; -import org.opencb.opencga.storage.core.variant.query.VariantQueryResult; import org.opencb.opencga.core.testclassification.duration.LongTests; import org.opencb.opencga.storage.core.variant.VariantStorageEngineSVTest; import org.opencb.opencga.storage.core.variant.adaptors.GenotypeClass; import org.opencb.opencga.storage.core.variant.adaptors.VariantQuery; -import org.opencb.opencga.storage.core.variant.adaptors.VariantQueryParam; +import org.opencb.opencga.storage.core.variant.query.VariantQueryResult; import org.opencb.opencga.storage.hadoop.variant.adaptors.VariantHadoopDBAdaptor; import java.util.HashSet; import java.util.List; +import java.util.Map; import java.util.Set; import static org.junit.Assert.assertEquals; @@ -45,17 +45,26 @@ public void checkSampleIndex() throws Exception { .includeSampleId(true) , new QueryOptions())) { Set samplesInVariant = new HashSet<>(); - for (String sample : metadataManager.getIndexedSamplesMap(studyMetadata.getId()).keySet()) { - QueryOptions options = new QueryOptions(VariantHadoopDBAdaptor.NATIVE, false); - VariantQueryResult result = variantStorageEngine.get(new Query() - .append(VariantQueryParam.SAMPLE.key(), sample) - .append(VariantQueryParam.ID.key(), variant.toString()), options); - String genotype = variant.getStudies().get(0).getSample(sample).getData().get(0); - if (GenotypeClass.MAIN_ALT.test(genotype)) { - Assert.assertNotNull(result.first()); - samplesInVariant.add(sample); - } else { - Assert.assertNull("Sample=" + sample + " with GT=" + genotype + " in variant=" + variant, result.first()); + for (Map.Entry entry : metadataManager.getStudies().entrySet()) { + String studyName = entry.getKey(); + Integer studyId = entry.getValue(); + StudyEntry studyEntry = variant.getStudy(studyName); + if (studyEntry != null) { + for (String sample : metadataManager.getIndexedSamplesMap(studyId).keySet()) { + QueryOptions options = new QueryOptions(VariantHadoopDBAdaptor.NATIVE, false); + VariantQueryResult result = variantStorageEngine.get(new VariantQuery() + .study(studyName) + .id(variant.toString()) + .sample(sample), options); + String genotype = studyEntry.getSample(sample).getData().get(0); + String message = "Study=" + studyName + " Sample=" + sample + " with GT=" + genotype + " in variant=" + variant; + if (GenotypeClass.MAIN_ALT.test(genotype)) { + Assert.assertNotNull(message, result.first()); + samplesInVariant.add(sample); + } else { + Assert.assertNull(message, result.first()); + } + } } } List actualSampleNames = variantStorageEngine.getSampleData(variant.toString(), studyMetadata.getName(), new QueryOptions()).first().getSampleNames(studyMetadata.getName()); diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/test/java/org/opencb/opencga/storage/hadoop/variant/VariantHadoopStoragePipelineTest.java b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/test/java/org/opencb/opencga/storage/hadoop/variant/VariantHadoopStoragePipelineTest.java index 7abd5c71449..773f017a67c 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/test/java/org/opencb/opencga/storage/hadoop/variant/VariantHadoopStoragePipelineTest.java +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/test/java/org/opencb/opencga/storage/hadoop/variant/VariantHadoopStoragePipelineTest.java @@ -207,7 +207,7 @@ public void checkVariantTable() throws IOException { int num = 0; ResultScanner resultScanner = table.getScanner(GenomeHelper.COLUMN_FAMILY_BYTES); for (Result result : resultScanner) { - Variant variant = VariantPhoenixKeyFactory.extractVariantFromVariantRowKey(result.getRow()); + Variant variant = VariantPhoenixKeyFactory.extractVariantFromResult(result); System.out.println("Variant = " + variant); num++; } diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/test/java/org/opencb/opencga/storage/hadoop/variant/VariantHbaseTestUtils.java b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/test/java/org/opencb/opencga/storage/hadoop/variant/VariantHbaseTestUtils.java index 3557c5e55ff..0acd7cfa919 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/test/java/org/opencb/opencga/storage/hadoop/variant/VariantHbaseTestUtils.java +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/test/java/org/opencb/opencga/storage/hadoop/variant/VariantHbaseTestUtils.java @@ -64,6 +64,7 @@ import java.io.*; import java.net.URI; +import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.*; @@ -72,7 +73,6 @@ import java.util.zip.DataFormatException; import static org.opencb.opencga.storage.core.variant.VariantStorageBaseTest.getTmpRootDir; -import static org.opencb.opencga.storage.hadoop.variant.HadoopVariantStorageTest.configuration; /** * Utility class for VariantStorage hadoop tests @@ -159,7 +159,7 @@ public static void printVariantsFromVariantsTable(VariantHadoopDBAdaptor dbAdapt for (Result result : resultScanner) { Variant variant; try { - variant = VariantPhoenixKeyFactory.extractVariantFromVariantRowKey(result.getRow()); + variant = VariantPhoenixKeyFactory.extractVariantFromResult(result); } catch (RuntimeException e) { os.println(Arrays.toString(result.getRow())); os.println("--------------------"); @@ -406,7 +406,7 @@ public static void printVariants(Collection studies, VariantHadoo } private static void printVcf(StudyMetadata studyMetadata, VariantHadoopDBAdaptor dbAdaptor, Path outDir) throws IOException { - try (OutputStream os = new FileOutputStream(outDir.resolve("variant." + studyMetadata.getName() + ".vcf").toFile())) { + try (OutputStream os = Files.newOutputStream(outDir.resolve("variant." + studyMetadata.getName() + ".vcf"))) { Query query = new Query(VariantQueryParam.STUDY.key(), studyMetadata.getName()) .append(VariantQueryParam.INCLUDE_SAMPLE.key(), ParamConstants.ALL) .append(VariantQueryParam.UNKNOWN_GENOTYPE.key(), "."); diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/test/java/org/opencb/opencga/storage/hadoop/variant/adaptors/phoenix/VariantPhoenixKeyFactoryTest.java b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/test/java/org/opencb/opencga/storage/hadoop/variant/adaptors/phoenix/VariantPhoenixKeyFactoryTest.java index 292b5c504a4..9e03dcca8b2 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/test/java/org/opencb/opencga/storage/hadoop/variant/adaptors/phoenix/VariantPhoenixKeyFactoryTest.java +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/test/java/org/opencb/opencga/storage/hadoop/variant/adaptors/phoenix/VariantPhoenixKeyFactoryTest.java @@ -1,5 +1,9 @@ package org.opencb.opencga.storage.hadoop.variant.adaptors.phoenix; +import org.apache.commons.lang.RandomStringUtils; +import org.apache.hadoop.hbase.HConstants; +import org.apache.hadoop.hbase.KeyValue; +import org.apache.hadoop.hbase.client.Result; import org.apache.hadoop.hbase.io.ImmutableBytesWritable; import org.apache.hadoop.hbase.util.ByteStringer; import org.apache.hadoop.hbase.util.Bytes; @@ -11,7 +15,9 @@ import org.junit.experimental.categories.Category; import org.junit.rules.ExpectedException; import org.opencb.biodata.models.variant.Variant; +import org.opencb.biodata.models.variant.avro.StructuralVariation; import org.opencb.opencga.core.testclassification.duration.ShortTests; +import org.opencb.opencga.storage.hadoop.variant.GenomeHelper; import java.sql.SQLException; import java.util.*; @@ -53,6 +59,16 @@ public void testStructuralVariantRowKey() throws Exception { checkVariantRowKeyGeneration(new Variant("5:100:A:A]:chr5:234]")); } + @Test + public void testExtraLargeVariantRowKey() throws Exception { + String allele1 = RandomStringUtils.random(50000, "ACGT"); + checkVariantRowKeyGeneration(new Variant("5:1000:-:" + allele1)); + StructuralVariation sv = new StructuralVariation(); + sv.setLeftSvInsSeq(allele1); + sv.setRightSvInsSeq(allele1); + checkVariantRowKeyGeneration(new Variant("5:1000:A:").setSv(sv)); + } + @Test public void testExtractChrPosFromVariantRowKeyPartial() { byte[] phoenixRowKey = VariantPhoenixKeyFactory.generateVariantRowKey("1", 20 << 16); @@ -72,16 +88,23 @@ public void checkVariantRowKeyGeneration(Variant variant) { // System.out.println("expected = " + Bytes.toStringBinary(phoenixRowKey)); byte[] variantRowkey = VariantPhoenixKeyFactory.generateVariantRowKey(variant); + byte[] alleles = Bytes.toBytes(VariantPhoenixKeyFactory.buildAlleles(variant)); // System.out.println("actual = " + Bytes.toStringBinary(variantRowkey)); - Variant generatedVariant = VariantPhoenixKeyFactory.extractVariantFromVariantRowKey(variantRowkey); + Variant generatedVariant = VariantPhoenixKeyFactory.extractVariantFromVariantRowKey(variantRowkey, null, alleles); + + Result result = Result.create(Collections.singletonList(new KeyValue(phoenixRowKey, GenomeHelper.COLUMN_FAMILY_BYTES, VariantPhoenixSchema.VariantColumn.ALLELES.bytes(), + alleles))); + + Variant generatedVariant2 = VariantPhoenixKeyFactory.extractVariantFromResult(result); assertArrayEquals(variant.toString(), phoenixRowKey, variantRowkey); assertEquals(variant, generatedVariant); + assertEquals(variant, generatedVariant2); } public byte[] generateVariantRowKeyPhoenix(Variant variant) { - Set nullableColumn = new HashSet<>(Arrays.asList( + Set nullableColumn = new HashSet<>(Arrays.asList( VariantPhoenixSchema.VariantColumn.REFERENCE, VariantPhoenixSchema.VariantColumn.ALTERNATE )); @@ -104,12 +127,23 @@ public byte[] generateVariantRowKeyPhoenix(Variant variant) { } ImmutableBytesWritable key = new ImmutableBytesWritable(); + String reference = variant.getReference(); + String alternate = VariantPhoenixKeyFactory.buildSymbolicAlternate(reference, variant.getAlternate(), variant.getEnd(), variant.getSv()); table.newKey(key, new byte[][]{ Bytes.toBytes(variant.getChromosome()), Bytes.toBytes(variant.getStart()), - Bytes.toBytes(variant.getReference()), - Bytes.toBytes(VariantPhoenixKeyFactory.buildSymbolicAlternate(variant.getReference(), variant.getAlternate(), variant.getEnd(), variant.getSv())), + Bytes.toBytes(reference), + Bytes.toBytes(alternate), }); + if (key.getLength() > HConstants.MAX_ROW_LENGTH) { + key = new ImmutableBytesWritable(); + table.newKey(key, new byte[][]{ + Bytes.toBytes(variant.getChromosome()), + Bytes.toBytes(variant.getStart()), + Bytes.toBytes(VariantPhoenixKeyFactory.hashAllele(reference)), + Bytes.toBytes(VariantPhoenixKeyFactory.hashAllele(alternate)), + }); + } if (key.getLength() == key.get().length) { return key.get(); diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/test/java/org/opencb/opencga/storage/hadoop/variant/gaps/FillGapsTest.java b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/test/java/org/opencb/opencga/storage/hadoop/variant/gaps/FillGapsTest.java index a2e6699180d..fdb5d42f1b9 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/test/java/org/opencb/opencga/storage/hadoop/variant/gaps/FillGapsTest.java +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/test/java/org/opencb/opencga/storage/hadoop/variant/gaps/FillGapsTest.java @@ -356,8 +356,7 @@ private void checkInputValuesAreUnmodified(String aggregatedStudy, String refere dbAdaptor.getHBaseManager().act(dbAdaptor.getVariantTable(), table -> { table.getScanner(new Scan()).iterator().forEachRemaining(r -> { - byte[] row = r.getRow(); - Variant variant = VariantPhoenixKeyFactory.extractVariantFromVariantRowKey(row); + Variant variant = VariantPhoenixKeyFactory.extractVariantFromResult(r); NavigableMap cells = r.getFamilyMap(GenomeHelper.COLUMN_FAMILY_BYTES); for (Map.Entry entry : cells.entrySet()) { From 4b2b4e85119fc6a68122aa61446271972d30dacf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacobo=20Coll=20Morag=C3=B3n?= Date: Fri, 10 May 2024 18:20:45 +0100 Subject: [PATCH 66/85] app: Add migration to register new ALLELES column to phoenix. #TASK-6005 --- .../storage/AddAllelesColumnToPhoenix.java | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 opencga-app/src/main/java/org/opencb/opencga/app/migrations/v2_12_5/storage/AddAllelesColumnToPhoenix.java diff --git a/opencga-app/src/main/java/org/opencb/opencga/app/migrations/v2_12_5/storage/AddAllelesColumnToPhoenix.java b/opencga-app/src/main/java/org/opencb/opencga/app/migrations/v2_12_5/storage/AddAllelesColumnToPhoenix.java new file mode 100644 index 00000000000..c71f0483427 --- /dev/null +++ b/opencga-app/src/main/java/org/opencb/opencga/app/migrations/v2_12_5/storage/AddAllelesColumnToPhoenix.java @@ -0,0 +1,27 @@ +package org.opencb.opencga.app.migrations.v2_12_5.storage; + +import org.opencb.opencga.app.migrations.StorageMigrationTool; +import org.opencb.opencga.catalog.migration.Migration; +import org.opencb.opencga.storage.core.variant.VariantStorageEngine; + +@Migration(id="add_missing_column_to_phoenix_TASK-6005", description = "Add missing ALLELES column to phoenix #TASK-6005", + version = "2.12.5", domain = Migration.MigrationDomain.STORAGE, date = 20240510 +) +public class AddAllelesColumnToPhoenix extends StorageMigrationTool { + + @Override + protected void run() throws Exception { + for (String project : getVariantStorageProjects()) { + VariantStorageEngine engine = getVariantStorageEngineByProject(project); + if (engine.getStorageEngineId().equals("hadoop")) { + logger.info("Adding missing columns (if any) for project " + project); + // Using same class for both migrations + Class aClass = Class.forName("org.opencb.opencga.storage.hadoop.variant.migration.v2_3_0.AddMissingColumns"); + Runnable runnable = (Runnable) aClass + .getConstructor(Object.class) + .newInstance(engine); + runnable.run(); + } + } + } +} \ No newline at end of file From 899cadd4c1f813d99949e534172858db825125c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacobo=20Coll=20Morag=C3=B3n?= Date: Tue, 14 May 2024 10:37:33 +0100 Subject: [PATCH 67/85] storage: Fix sampleData query with hashed alleles. #TASK-6005 --- .../phoenix/VariantPhoenixKeyFactory.java | 29 +++++++++++++-- .../sample/HBaseVariantSampleDataManager.java | 16 ++++----- .../hadoop/variant/converters/VariantRow.java | 35 +++++++++++++++---- .../HadoopVariantStorageEngineSVTest.java | 11 ++++-- 4 files changed, 73 insertions(+), 18 deletions(-) diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/adaptors/phoenix/VariantPhoenixKeyFactory.java b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/adaptors/phoenix/VariantPhoenixKeyFactory.java index 1d78af0d860..f61cfdcc464 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/adaptors/phoenix/VariantPhoenixKeyFactory.java +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/adaptors/phoenix/VariantPhoenixKeyFactory.java @@ -65,6 +65,26 @@ public static byte[] generateVariantRowKey(Variant var) { var.getSv()); } + public static byte[] generateVariantRowKey(ResultSet resultSet) { + String chromosome = null; + Integer start = null; + String reference = null; + String alternate = null; + try { + chromosome = resultSet.getString(VariantPhoenixSchema.VariantColumn.CHROMOSOME.column()); + start = resultSet.getInt(VariantPhoenixSchema.VariantColumn.POSITION.column()); + reference = resultSet.getString(VariantPhoenixSchema.VariantColumn.REFERENCE.column()); + alternate = resultSet.getString(VariantPhoenixSchema.VariantColumn.ALTERNATE.column()); + + return generateVariantRowKey(chromosome, start, null, reference, alternate, null); + } catch (RuntimeException | SQLException e) { + throw new IllegalStateException("Fail to generate row key from Phoenix result set: " + chromosome + + ':' + start + + ':' + (reference == null ? "-" : reference) + + ':' + (alternate == null ? "-" : alternate), e); + } + } + public static byte[] generateVariantRowKey(VariantAnnotation variantAnnotation) { byte[] bytesRowKey = null; if (variantAnnotation.getAdditionalAttributes() != null) { @@ -104,11 +124,11 @@ public static byte[] generateSimpleVariantRowKey(String chrom, int position, Str } public static boolean mightHashAlleles(Variant variant) { - String alt = buildSymbolicAlternate(variant.getReference(), variant.getAlternate(), variant.getEnd(), variant.getSv()); - int size = getSize(variant.getChromosome(), variant.getReference(), variant.getAlternate()); + int size = getSize(variant); return size > HConstants.MAX_ROW_LENGTH; } + /** * Generates a Row key based on Chromosome, start, end (optional), ref and alt.
    *
      @@ -155,6 +175,11 @@ public static byte[] generateVariantRowKey(String chrom, int start, Integer end, return rk; } + private static int getSize(Variant variant) { + String symbolicAlternate = buildSymbolicAlternate(variant); + return getSize(variant.getChromosome(), variant.getReference(), symbolicAlternate); + } + private static int getSize(String chrom, String ref, String alt) { int size = PVarchar.INSTANCE.estimateByteSizeFromLength(chrom.length()) + QueryConstants.SEPARATOR_BYTE_ARRAY.length diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/adaptors/sample/HBaseVariantSampleDataManager.java b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/adaptors/sample/HBaseVariantSampleDataManager.java index 6f426b59c43..65bff54948f 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/adaptors/sample/HBaseVariantSampleDataManager.java +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/adaptors/sample/HBaseVariantSampleDataManager.java @@ -127,7 +127,7 @@ protected DataResult getSampleData(Variant variant, String study, Query samples.add(sampleColumn.getSampleId()); sampleDataMap.add(sampleColumn); } - }).walk(); + }).walk(variant); } }); @@ -138,8 +138,7 @@ protected DataResult getSampleData(Variant variant, String study, Query List stats = new LinkedList<>(); dbAdaptor.getHBaseManager().act(dbAdaptor.getVariantTable(), table -> { Get get = new Get(VariantPhoenixKeyFactory.generateVariantRowKey(variant)); - get.addColumn(GenomeHelper.COLUMN_FAMILY_BYTES, VariantPhoenixSchema.VariantColumn.TYPE.bytes()); - get.addColumn(GenomeHelper.COLUMN_FAMILY_BYTES, VariantPhoenixSchema.VariantColumn.ALLELES.bytes()); + // Add file columns for (Integer fileId : fileIdsFromSampleIds) { get.addColumn(GenomeHelper.COLUMN_FAMILY_BYTES, VariantPhoenixSchema.buildFileColumnKey(studyId, fileId)); @@ -178,7 +177,7 @@ protected DataResult getSampleData(Variant variant, String study, Query ImmutableBytesWritable b = column.toBytesWritable(); variant.setAnnotation(new HBaseToVariantAnnotationConverter().convert(b.get(), b.getOffset(), b.getLength())); }) - .walk(); + .walk(variant); }); // Convert to VariantSampleData @@ -194,13 +193,14 @@ protected DataResult getSampleData(Variant variant, String study, Query new ArrayList<>(fileIdsFromSampleIds))) .build()); - StudyEntry studyEntry = converter.convert(sampleDataMap, filesMap, variant, studyId); + Variant variantResult = new Variant(variant.toString()); + StudyEntry studyEntry = converter.convert(sampleDataMap, filesMap, variantResult, studyId); - variant.addStudyEntry(studyEntry); + variantResult.addStudyEntry(studyEntry); studyEntry.setStats(stats); -// String msg = "Queries : " + queries + " , readSamples : " + readSamples; + return new DataResult<>((int) stopWatch.getTime(TimeUnit.MILLISECONDS), Collections.emptyList(), 1, - Collections.singletonList(variant), 1); + Collections.singletonList(variantResult), 1); } catch (IOException e) { throw VariantQueryException.internalException(e); } diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/converters/VariantRow.java b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/converters/VariantRow.java index f3700d24d15..6f4ee0ad344 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/converters/VariantRow.java +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/converters/VariantRow.java @@ -64,8 +64,6 @@ public static VariantRowWalkerBuilder walker(ResultSet resultSet) { public Variant getVariant() { if (variant == null) { if (result != null) { - byte[] row = result.getRow(); - Objects.requireNonNull(row, "Empty result. Missing variant rowkey."); variant = VariantPhoenixKeyFactory.extractVariantFromResult(result); } else { variant = VariantPhoenixKeyFactory.extractVariantFromResultSet(resultSet); @@ -104,11 +102,27 @@ public VariantRowWalkerBuilder walker() { } public void walk(VariantRowWalker walker) { - walk(walker, true, true, true, true, true); + walk(walker, true, true, true, true, true, null); } - protected void walk(VariantRowWalker walker, boolean file, boolean sample, boolean cohort, boolean score, boolean annotation) { - walker.variant(getVariant()); + protected void walk(VariantRowWalker walker, boolean file, boolean sample, boolean cohort, boolean score, boolean annotation, + Variant variant) { + if (variant == null) { + variant = getVariant(); + } else { + byte[] expectedRow = VariantPhoenixKeyFactory.generateVariantRowKey(variant); + byte[] actualRow; + if (result != null) { + actualRow = result.getRow(); + } else { + actualRow = VariantPhoenixKeyFactory.generateVariantRowKey(resultSet); + } + if (!Bytes.equals(expectedRow, actualRow)) { + throw new IllegalStateException("Expected row " + + Bytes.toStringBinary(expectedRow) + " but got " + Bytes.toStringBinary(actualRow)); + } + } + walker.variant(variant); if (resultSet != null) { try { ResultSetMetaData metaData = resultSet.getMetaData(); @@ -280,10 +294,19 @@ public Variant walk() { hasSampleConsumer, hasStatsConsumer, hasVariantScoreConsumer, - hasVariantAnnotationConsummer); + hasVariantAnnotationConsummer, null); return getVariant(); } + public void walk(Variant variant) { + VariantRow.this.walk(this, + hasFileConsumer, + hasSampleConsumer, + hasStatsConsumer, + hasVariantScoreConsumer, + hasVariantAnnotationConsummer, variant); + } + public VariantRowWalkerBuilder onStudy(IntConsumer consumer) { studyConsumer = consumer; return this; diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/test/java/org/opencb/opencga/storage/hadoop/variant/HadoopVariantStorageEngineSVTest.java b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/test/java/org/opencb/opencga/storage/hadoop/variant/HadoopVariantStorageEngineSVTest.java index e46e1bb6782..a6f5611df09 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/test/java/org/opencb/opencga/storage/hadoop/variant/HadoopVariantStorageEngineSVTest.java +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/test/java/org/opencb/opencga/storage/hadoop/variant/HadoopVariantStorageEngineSVTest.java @@ -13,6 +13,8 @@ import org.opencb.opencga.storage.core.variant.adaptors.VariantQuery; import org.opencb.opencga.storage.core.variant.query.VariantQueryResult; import org.opencb.opencga.storage.hadoop.variant.adaptors.VariantHadoopDBAdaptor; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.util.HashSet; import java.util.List; @@ -31,6 +33,7 @@ public class HadoopVariantStorageEngineSVTest extends VariantStorageEngineSVTest @ClassRule public static HadoopExternalResource externalResource = new HadoopExternalResource(); + private Logger logger = LoggerFactory.getLogger(getClass()); @Override protected void loadFiles() throws Exception { @@ -65,10 +68,14 @@ public void checkSampleIndex() throws Exception { Assert.assertNull(message, result.first()); } } + logger.info("Variant " + variant + " with samples " + samplesInVariant); + logger.info("Query variant " + variant + " in study " + studyName + " from sampleData"); + Variant sampleDataVariant = variantStorageEngine.getSampleData(variant.toString(), studyName, new QueryOptions()).first(); + List actualSampleNames = sampleDataVariant.getSampleNames(studyName); + logger.info("Variant " + variant + " with actual samples " + actualSampleNames); + Assert.assertEquals(samplesInVariant, new HashSet<>(actualSampleNames)); } } - List actualSampleNames = variantStorageEngine.getSampleData(variant.toString(), studyMetadata.getName(), new QueryOptions()).first().getSampleNames(studyMetadata.getName()); - Assert.assertEquals(samplesInVariant, new HashSet<>(actualSampleNames)); } } From ae5340cdea3c522028834bf8af03c1f26aa29b5b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacobo=20Coll=20Morag=C3=B3n?= Date: Tue, 14 May 2024 10:48:27 +0100 Subject: [PATCH 68/85] storage: Add missing id to variants from sampleData query. #TASK-6005 --- .../variant/adaptors/sample/HBaseVariantSampleDataManager.java | 1 + 1 file changed, 1 insertion(+) diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/adaptors/sample/HBaseVariantSampleDataManager.java b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/adaptors/sample/HBaseVariantSampleDataManager.java index 65bff54948f..659e401d88e 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/adaptors/sample/HBaseVariantSampleDataManager.java +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/adaptors/sample/HBaseVariantSampleDataManager.java @@ -194,6 +194,7 @@ protected DataResult getSampleData(Variant variant, String study, Query .build()); Variant variantResult = new Variant(variant.toString()); + variantResult.setId(variant.toString()); StudyEntry studyEntry = converter.convert(sampleDataMap, filesMap, variantResult, studyId); variantResult.addStudyEntry(studyEntry); From 9516a2f2b57edabf00139b1f8d616b9c1dd3faeb Mon Sep 17 00:00:00 2001 From: JuanfeSanahuja Date: Tue, 14 May 2024 13:11:53 +0200 Subject: [PATCH 69/85] pom: Prepare Port Patch 1.10.4.1 -> 1.10.5 #TASK-6231 --- opencga-analysis/pom.xml | 2 +- opencga-app/pom.xml | 2 +- opencga-catalog/pom.xml | 2 +- opencga-client/pom.xml | 2 +- opencga-clinical/pom.xml | 2 +- opencga-core/pom.xml | 2 +- opencga-master/pom.xml | 2 +- opencga-server/pom.xml | 2 +- opencga-storage/opencga-storage-app/pom.xml | 2 +- opencga-storage/opencga-storage-benchmark/pom.xml | 2 +- opencga-storage/opencga-storage-core/pom.xml | 2 +- .../opencga-storage-hadoop/opencga-storage-hadoop-core/pom.xml | 2 +- .../opencga-storage-hadoop-deps-emr6.1/pom.xml | 2 +- .../opencga-storage-hadoop-deps-hdp2.6/pom.xml | 2 +- .../opencga-storage-hadoop-deps-hdp3.1/pom.xml | 2 +- .../opencga-storage-hadoop/opencga-storage-hadoop-deps/pom.xml | 2 +- opencga-storage/opencga-storage-hadoop/pom.xml | 2 +- opencga-storage/opencga-storage-server/pom.xml | 2 +- opencga-storage/pom.xml | 2 +- opencga-test/pom.xml | 2 +- pom.xml | 2 +- 21 files changed, 21 insertions(+), 21 deletions(-) diff --git a/opencga-analysis/pom.xml b/opencga-analysis/pom.xml index e6ff1cdab39..0e8c8b94814 100644 --- a/opencga-analysis/pom.xml +++ b/opencga-analysis/pom.xml @@ -22,7 +22,7 @@ org.opencb.opencga opencga - 2.12.4.1 + 2.12.5-SNAPSHOT ../pom.xml diff --git a/opencga-app/pom.xml b/opencga-app/pom.xml index 8338fed6637..ae72959c680 100644 --- a/opencga-app/pom.xml +++ b/opencga-app/pom.xml @@ -22,7 +22,7 @@ org.opencb.opencga opencga - 2.12.4.1 + 2.12.5-SNAPSHOT ../pom.xml diff --git a/opencga-catalog/pom.xml b/opencga-catalog/pom.xml index 3c04b120d94..120850f20f8 100644 --- a/opencga-catalog/pom.xml +++ b/opencga-catalog/pom.xml @@ -23,7 +23,7 @@ org.opencb.opencga opencga - 2.12.4.1 + 2.12.5-SNAPSHOT ../pom.xml diff --git a/opencga-client/pom.xml b/opencga-client/pom.xml index 6bfc198dbd2..dfe20bc1c6d 100644 --- a/opencga-client/pom.xml +++ b/opencga-client/pom.xml @@ -22,7 +22,7 @@ org.opencb.opencga opencga - 2.12.4.1 + 2.12.5-SNAPSHOT ../pom.xml diff --git a/opencga-clinical/pom.xml b/opencga-clinical/pom.xml index 091f182629c..e17ae02a3c5 100644 --- a/opencga-clinical/pom.xml +++ b/opencga-clinical/pom.xml @@ -5,7 +5,7 @@ org.opencb.opencga opencga - 2.12.4.1 + 2.12.5-SNAPSHOT ../pom.xml 4.0.0 diff --git a/opencga-core/pom.xml b/opencga-core/pom.xml index aa0b7536f33..f64f0c82cd5 100644 --- a/opencga-core/pom.xml +++ b/opencga-core/pom.xml @@ -22,7 +22,7 @@ org.opencb.opencga opencga - 2.12.4.1 + 2.12.5-SNAPSHOT ../pom.xml diff --git a/opencga-master/pom.xml b/opencga-master/pom.xml index 7d734c21008..3010de9e741 100644 --- a/opencga-master/pom.xml +++ b/opencga-master/pom.xml @@ -22,7 +22,7 @@ opencga org.opencb.opencga - 2.12.4.1 + 2.12.5-SNAPSHOT ../pom.xml diff --git a/opencga-server/pom.xml b/opencga-server/pom.xml index 995f35ba347..35730710dd5 100644 --- a/opencga-server/pom.xml +++ b/opencga-server/pom.xml @@ -22,7 +22,7 @@ org.opencb.opencga opencga - 2.12.4.1 + 2.12.5-SNAPSHOT ../pom.xml diff --git a/opencga-storage/opencga-storage-app/pom.xml b/opencga-storage/opencga-storage-app/pom.xml index 94bff4c00ef..dee5f5ab22d 100644 --- a/opencga-storage/opencga-storage-app/pom.xml +++ b/opencga-storage/opencga-storage-app/pom.xml @@ -22,7 +22,7 @@ org.opencb.opencga opencga-storage - 2.12.4.1 + 2.12.5-SNAPSHOT ../pom.xml diff --git a/opencga-storage/opencga-storage-benchmark/pom.xml b/opencga-storage/opencga-storage-benchmark/pom.xml index 40cf18bfb8c..f566fb8d61a 100644 --- a/opencga-storage/opencga-storage-benchmark/pom.xml +++ b/opencga-storage/opencga-storage-benchmark/pom.xml @@ -22,7 +22,7 @@ opencga-storage org.opencb.opencga - 2.12.4.1 + 2.12.5-SNAPSHOT ../pom.xml diff --git a/opencga-storage/opencga-storage-core/pom.xml b/opencga-storage/opencga-storage-core/pom.xml index ccf5ad0c257..d2569f51505 100644 --- a/opencga-storage/opencga-storage-core/pom.xml +++ b/opencga-storage/opencga-storage-core/pom.xml @@ -22,7 +22,7 @@ org.opencb.opencga opencga-storage - 2.12.4.1 + 2.12.5-SNAPSHOT ../pom.xml diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/pom.xml b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/pom.xml index ded68c578bf..98684f89345 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/pom.xml +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/pom.xml @@ -23,7 +23,7 @@ org.opencb.opencga opencga-storage-hadoop - 2.12.4.1 + 2.12.5-SNAPSHOT ../pom.xml diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-deps/opencga-storage-hadoop-deps-emr6.1/pom.xml b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-deps/opencga-storage-hadoop-deps-emr6.1/pom.xml index 28d392a9ea7..c40bd0c545e 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-deps/opencga-storage-hadoop-deps-emr6.1/pom.xml +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-deps/opencga-storage-hadoop-deps-emr6.1/pom.xml @@ -22,7 +22,7 @@ org.opencb.opencga opencga-storage-hadoop-deps - 2.12.4.1 + 2.12.5-SNAPSHOT ../pom.xml diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-deps/opencga-storage-hadoop-deps-hdp2.6/pom.xml b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-deps/opencga-storage-hadoop-deps-hdp2.6/pom.xml index 5c40b34b0b9..f2ab268c070 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-deps/opencga-storage-hadoop-deps-hdp2.6/pom.xml +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-deps/opencga-storage-hadoop-deps-hdp2.6/pom.xml @@ -22,7 +22,7 @@ org.opencb.opencga opencga-storage-hadoop-deps - 2.12.4.1 + 2.12.5-SNAPSHOT ../pom.xml diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-deps/opencga-storage-hadoop-deps-hdp3.1/pom.xml b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-deps/opencga-storage-hadoop-deps-hdp3.1/pom.xml index ed33bf0043b..c78627c4980 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-deps/opencga-storage-hadoop-deps-hdp3.1/pom.xml +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-deps/opencga-storage-hadoop-deps-hdp3.1/pom.xml @@ -22,7 +22,7 @@ org.opencb.opencga opencga-storage-hadoop-deps - 2.12.4.1 + 2.12.5-SNAPSHOT ../pom.xml diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-deps/pom.xml b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-deps/pom.xml index bb718594f50..5f0d66e4a26 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-deps/pom.xml +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-deps/pom.xml @@ -50,7 +50,7 @@ org.opencb.opencga opencga-storage-hadoop - 2.12.4.1 + 2.12.5-SNAPSHOT ../pom.xml diff --git a/opencga-storage/opencga-storage-hadoop/pom.xml b/opencga-storage/opencga-storage-hadoop/pom.xml index 510bd72eaac..ede0e9d5479 100644 --- a/opencga-storage/opencga-storage-hadoop/pom.xml +++ b/opencga-storage/opencga-storage-hadoop/pom.xml @@ -28,7 +28,7 @@ org.opencb.opencga opencga-storage - 2.12.4.1 + 2.12.5-SNAPSHOT ../pom.xml diff --git a/opencga-storage/opencga-storage-server/pom.xml b/opencga-storage/opencga-storage-server/pom.xml index a3fe6497eb8..46032914536 100644 --- a/opencga-storage/opencga-storage-server/pom.xml +++ b/opencga-storage/opencga-storage-server/pom.xml @@ -22,7 +22,7 @@ org.opencb.opencga opencga-storage - 2.12.4.1 + 2.12.5-SNAPSHOT ../pom.xml diff --git a/opencga-storage/pom.xml b/opencga-storage/pom.xml index 3284f8c8670..b318a6c26bb 100644 --- a/opencga-storage/pom.xml +++ b/opencga-storage/pom.xml @@ -22,7 +22,7 @@ org.opencb.opencga opencga - 2.12.4.1 + 2.12.5-SNAPSHOT ../pom.xml diff --git a/opencga-test/pom.xml b/opencga-test/pom.xml index 6baa1797a71..ae075a55888 100644 --- a/opencga-test/pom.xml +++ b/opencga-test/pom.xml @@ -24,7 +24,7 @@ org.opencb.opencga opencga - 2.12.4.1 + 2.12.5-SNAPSHOT ../pom.xml diff --git a/pom.xml b/pom.xml index 60f9eabe132..2f28d2235d5 100644 --- a/pom.xml +++ b/pom.xml @@ -22,7 +22,7 @@ org.opencb.opencga opencga - 2.12.4.1 + 2.12.5-SNAPSHOT pom OpenCGA From fcd121aae1e21203a785e05ed14a37dd87a66dfb Mon Sep 17 00:00:00 2001 From: JuanfeSanahuja Date: Tue, 14 May 2024 13:14:06 +0200 Subject: [PATCH 70/85] pom: Prepare Port Patch 1.10.4.1 -> 1.10.5 #TASK-6231 --- pom.xml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/pom.xml b/pom.xml index 2f28d2235d5..29536c3be50 100644 --- a/pom.xml +++ b/pom.xml @@ -43,12 +43,12 @@ - - 2.12.4.1 - 5.8.3 - 2.12.2 - 4.12.0 - 2.12.4 + 2.12.5_dev + 2.12.5_dev + 5.8.4-SNAPSHOT + 2.12.3-SNAPSHOT + 4.12.1-SNAPSHOT + 2.12.5-SNAPSHOT 0.2.0 2.11.4 From 1ffe645441c58cf4d673732a5e1fd5b8a1f3ddb4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacobo=20Coll=20Morag=C3=B3n?= Date: Tue, 14 May 2024 14:02:34 +0100 Subject: [PATCH 71/85] storage: Ensure MR jobs read ALLELES column when needed. #TASK-6005 --- .../variant/VariantStorageEngineSVTest.java | 6 +++++- .../variant/analysis/julie/JulieToolDriver.java | 2 ++ .../mr/VariantAnnotationRebuilderDriver.java | 2 ++ .../variant/gaps/PrepareFillMissingDriver.java | 2 ++ .../mr/SampleIndexAnnotationLoaderDriver.java | 2 ++ .../mr/VariantTableSampleIndexOrderMapper.java | 17 ++++++++++++----- .../variant/index/family/FamilyIndexDriver.java | 3 ++- .../variant/index/sample/SampleIndexDriver.java | 15 ++++++++++----- .../variant/prune/VariantPruneDriver.java | 2 ++ .../variant/stats/SaturationStatsDriver.java | 1 + .../variant/stats/VariantHistogramDriver.java | 3 ++- .../variant/stats/VariantStatsDriver.java | 1 + .../HadoopVariantStorageEngineSVTest.java | 12 ++++++++---- 13 files changed, 51 insertions(+), 17 deletions(-) diff --git a/opencga-storage/opencga-storage-core/src/test/java/org/opencb/opencga/storage/core/variant/VariantStorageEngineSVTest.java b/opencga-storage/opencga-storage-core/src/test/java/org/opencb/opencga/storage/core/variant/VariantStorageEngineSVTest.java index 44ccd4f305a..64fc14c4c6a 100644 --- a/opencga-storage/opencga-storage-core/src/test/java/org/opencb/opencga/storage/core/variant/VariantStorageEngineSVTest.java +++ b/opencga-storage/opencga-storage-core/src/test/java/org/opencb/opencga/storage/core/variant/VariantStorageEngineSVTest.java @@ -70,18 +70,22 @@ protected void loadFiles() throws Exception { variantStorageEngine.getOptions().append(VariantStorageOptions.ANNOTATOR_CELLBASE_EXCLUDE.key(), "expression,clinical"); pipelineResult1 = runDefaultETL(input1, variantStorageEngine, studyMetadata, new QueryOptions() .append(VariantStorageOptions.ANNOTATE.key(), true) + .append(VariantStorageOptions.STATS_CALCULATE.key(), true) .append(VariantStorageOptions.ASSEMBLY.key(), "grch38") ); input2 = getResourceUri("variant-test-sv_2.vcf"); pipelineResult2 = runDefaultETL(input2, variantStorageEngine, studyMetadata, new QueryOptions() .append(VariantStorageOptions.ANNOTATE.key(), true) + .append(VariantStorageOptions.STATS_CALCULATE.key(), true) .append(VariantStorageOptions.ASSEMBLY.key(), "grch38")); input3 = getResourceUri("variant-test-sv-large.vcf"); studyMetadata2 = new StudyMetadata(2, "s2"); pipelineResult3 = runDefaultETL(input3, variantStorageEngine, studyMetadata2, new QueryOptions() - .append(VariantStorageOptions.ANNOTATE.key(), false) + .append(VariantStorageOptions.ANNOTATE.key(), true) + .append(VariantStorageOptions.STATS_CALCULATE.key(), true) .append(VariantStorageOptions.ASSEMBLY.key(), "grch38")); + } @Test diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/analysis/julie/JulieToolDriver.java b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/analysis/julie/JulieToolDriver.java index 4442bf48927..5192e7356f9 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/analysis/julie/JulieToolDriver.java +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/analysis/julie/JulieToolDriver.java @@ -79,6 +79,8 @@ protected void parseAndValidateParameters() throws IOException { @Override protected Job setupJob(Job job, String archiveTable, String variantTable) throws IOException { Scan scan = new Scan(); + scan.addColumn(GenomeHelper.COLUMN_FAMILY_BYTES, VariantPhoenixSchema.VariantColumn.TYPE.bytes()); + scan.addColumn(GenomeHelper.COLUMN_FAMILY_BYTES, VariantPhoenixSchema.VariantColumn.ALLELES.bytes()); scan.addColumn(GenomeHelper.COLUMN_FAMILY_BYTES, VariantPhoenixSchema.VariantColumn.FULL_ANNOTATION.bytes()); for (Map.Entry> entry : cohorts.entrySet()) { Integer studyId = entry.getKey(); diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/annotation/mr/VariantAnnotationRebuilderDriver.java b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/annotation/mr/VariantAnnotationRebuilderDriver.java index 5690b374981..eb4bdc5b4eb 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/annotation/mr/VariantAnnotationRebuilderDriver.java +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/annotation/mr/VariantAnnotationRebuilderDriver.java @@ -68,6 +68,8 @@ protected Job setupJob(Job job, String archiveTable, String variantTable) throws logger.info("Regenerate annotations for region " + region); VariantHBaseQueryParser.addRegionFilter(scan, new Region(region)); } + scan.addColumn(GenomeHelper.COLUMN_FAMILY_BYTES, VariantPhoenixSchema.VariantColumn.TYPE.bytes()); + scan.addColumn(GenomeHelper.COLUMN_FAMILY_BYTES, VariantPhoenixSchema.VariantColumn.ALLELES.bytes()); scan.addColumn(GenomeHelper.COLUMN_FAMILY_BYTES, VariantPhoenixSchema.VariantColumn.FULL_ANNOTATION.bytes()); VariantMapReduceUtil.configureMapReduceScan(scan, getConf()); diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/gaps/PrepareFillMissingDriver.java b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/gaps/PrepareFillMissingDriver.java index aea25583571..d760ab4543a 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/gaps/PrepareFillMissingDriver.java +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/gaps/PrepareFillMissingDriver.java @@ -62,6 +62,8 @@ protected Job setupJob(Job job, String archiveTableName, String variantTableName scan.setCacheBlocks(false); scan.addColumn(GenomeHelper.COLUMN_FAMILY_BYTES, VariantPhoenixSchema.getStudyColumn(getStudyId()).bytes()); scan.addColumn(GenomeHelper.COLUMN_FAMILY_BYTES, VariantPhoenixSchema.getFillMissingColumn(getStudyId()).bytes()); + scan.addColumn(GenomeHelper.COLUMN_FAMILY_BYTES, VariantPhoenixSchema.VariantColumn.ALLELES.bytes()); + scan.addColumn(GenomeHelper.COLUMN_FAMILY_BYTES, VariantPhoenixSchema.VariantColumn.TYPE.bytes()); LOG.info(scan.toString()); diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/index/annotation/mr/SampleIndexAnnotationLoaderDriver.java b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/index/annotation/mr/SampleIndexAnnotationLoaderDriver.java index 41826fd4abe..9f593f928c6 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/index/annotation/mr/SampleIndexAnnotationLoaderDriver.java +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/index/annotation/mr/SampleIndexAnnotationLoaderDriver.java @@ -138,6 +138,8 @@ protected Job setupJob(Job job, String archiveTable, String variantTable) throws } } scan.addColumn(GenomeHelper.COLUMN_FAMILY_BYTES, VariantPhoenixSchema.VariantColumn.FULL_ANNOTATION.bytes()); + scan.addColumn(GenomeHelper.COLUMN_FAMILY_BYTES, VariantPhoenixSchema.VariantColumn.TYPE.bytes()); + scan.addColumn(GenomeHelper.COLUMN_FAMILY_BYTES, VariantPhoenixSchema.VariantColumn.ALLELES.bytes()); SampleIndexAnnotationLoaderMapper.setHasGenotype(job, hasGenotype); SampleIndexAnnotationLoaderMapper.setMultiFileSamples(job, multiFileSamples); diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/index/annotation/mr/VariantTableSampleIndexOrderMapper.java b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/index/annotation/mr/VariantTableSampleIndexOrderMapper.java index cbf0952a876..ab9fc2a1d82 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/index/annotation/mr/VariantTableSampleIndexOrderMapper.java +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/index/annotation/mr/VariantTableSampleIndexOrderMapper.java @@ -51,11 +51,7 @@ public void run(Context context) throws IOException, InterruptedException { // Current result does not start in the previous position. // Sort buffer if (buffer.size() > 1) { - buffer.sort((o1, o2) -> { - Variant v1 = VariantPhoenixKeyFactory.extractVariantFromResult(o1.getSecond()); - Variant v2 = VariantPhoenixKeyFactory.extractVariantFromResult(o2.getSecond()); - return SampleIndexSchema.INTRA_CHROMOSOME_VARIANT_COMPARATOR.compare(v1, v2); - }); + sortBuffer(buffer); } if (!buffer.isEmpty()) { @@ -82,6 +78,9 @@ public void run(Context context) throws IOException, InterruptedException { } } countBufferSize(context, buffer.size(), chromosome, position); + if (buffer.size() > 1) { + sortBuffer(buffer); + } for (Pair pair : buffer) { this.map(pair.getFirst(), pair.getSecond(), context); } @@ -92,6 +91,14 @@ public void run(Context context) throws IOException, InterruptedException { } } + private static void sortBuffer(List> buffer) { + buffer.sort((o1, o2) -> { + Variant v1 = VariantPhoenixKeyFactory.extractVariantFromResult(o1.getSecond()); + Variant v2 = VariantPhoenixKeyFactory.extractVariantFromResult(o2.getSecond()); + return SampleIndexSchema.INTRA_CHROMOSOME_VARIANT_COMPARATOR.compare(v1, v2); + }); + } + private void countBufferSize(Context context, int size, String chromosome, int position) { String counterName; if (size < 5) { diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/index/family/FamilyIndexDriver.java b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/index/family/FamilyIndexDriver.java index ada52270419..af632d69436 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/index/family/FamilyIndexDriver.java +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/index/family/FamilyIndexDriver.java @@ -226,7 +226,8 @@ protected Job setupJob(Job job, String archiveTable, String variantTable) throws } } } -// scan.addColumn(getHelper().getColumnFamily(), VariantPhoenixHelper.VariantColumn.FULL_ANNOTATION.bytes()); + scan.addColumn(GenomeHelper.COLUMN_FAMILY_BYTES, VariantPhoenixSchema.VariantColumn.ALLELES.bytes()); + scan.addColumn(GenomeHelper.COLUMN_FAMILY_BYTES, VariantPhoenixSchema.VariantColumn.TYPE.bytes()); VariantMapReduceUtil.configureMapReduceScan(scan, getConf()); diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/index/sample/SampleIndexDriver.java b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/index/sample/SampleIndexDriver.java index d8488e87a8e..7b51d99fb85 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/index/sample/SampleIndexDriver.java +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/index/sample/SampleIndexDriver.java @@ -7,10 +7,7 @@ import org.apache.hadoop.hbase.client.Result; import org.apache.hadoop.hbase.client.Scan; import org.apache.hadoop.hbase.exceptions.IllegalArgumentIOException; -import org.apache.hadoop.hbase.filter.BinaryPrefixComparator; -import org.apache.hadoop.hbase.filter.FilterList; -import org.apache.hadoop.hbase.filter.QualifierFilter; -import org.apache.hadoop.hbase.filter.ValueFilter; +import org.apache.hadoop.hbase.filter.*; import org.apache.hadoop.hbase.io.ImmutableBytesWritable; import org.apache.hadoop.hbase.util.Bytes; import org.apache.hadoop.mapreduce.InputFormat; @@ -200,7 +197,7 @@ protected void parseAndValidateParameters() throws IOException { @Override protected Job setupJob(Job job, String archiveTable, String table) throws IOException { - FilterList filter = new FilterList(FilterList.Operator.MUST_PASS_ALL, + FilterList filterGt = new FilterList(FilterList.Operator.MUST_PASS_ALL, new QualifierFilter(EQUAL, new BinaryPrefixComparator(Bytes.toBytes(VariantPhoenixSchema.buildStudyColumnsPrefix(study)))), new ValueFilter(NOT_EQUAL, new BinaryPrefixComparator(new byte[]{'0', '|', '0', SEPARATOR_BYTE})), new ValueFilter(NOT_EQUAL, new BinaryPrefixComparator(new byte[]{'0', '/', '0', SEPARATOR_BYTE})), @@ -208,6 +205,10 @@ protected Job setupJob(Job job, String archiveTable, String table) throws IOExce new ValueFilter(NOT_EQUAL, new BinaryPrefixComparator(new byte[]{'.', '|', '.', SEPARATOR_BYTE})), new ValueFilter(NOT_EQUAL, new BinaryPrefixComparator(new byte[]{'.', SEPARATOR_BYTE})) ); + FilterList filter = new FilterList(FilterList.Operator.MUST_PASS_ONE, + new QualifierFilter(EQUAL, new BinaryComparator(VariantPhoenixSchema.VariantColumn.ALLELES.bytes())), + filterGt + ); List scans; if (multiScan) { @@ -220,6 +221,8 @@ protected Job setupJob(Job job, String archiveTable, String table) throws IOExce if (StringUtils.isNotEmpty(region)) { VariantHBaseQueryParser.addRegionFilter(scan, Region.parseRegion(region)); } + scan.addColumn(GenomeHelper.COLUMN_FAMILY_BYTES, VariantPhoenixSchema.VariantColumn.ALLELES.bytes()); + scan.addColumn(GenomeHelper.COLUMN_FAMILY_BYTES, VariantPhoenixSchema.VariantColumn.TYPE.bytes()); scan.setFilter(filter); scans.add(scan); for (int sample : samplesSubSet) { @@ -247,6 +250,8 @@ protected Job setupJob(Job job, String archiveTable, String table) throws IOExce VariantHBaseQueryParser.addRegionFilter(scan, Region.parseRegion(region)); } scan.setFilter(filter); + scan.addColumn(GenomeHelper.COLUMN_FAMILY_BYTES, VariantPhoenixSchema.VariantColumn.ALLELES.bytes()); + scan.addColumn(GenomeHelper.COLUMN_FAMILY_BYTES, VariantPhoenixSchema.VariantColumn.TYPE.bytes()); int approxExpectedNumColumns = sampleIds.size() diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/prune/VariantPruneDriver.java b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/prune/VariantPruneDriver.java index cf404e1daf5..fddaa7c189e 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/prune/VariantPruneDriver.java +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/prune/VariantPruneDriver.java @@ -96,6 +96,8 @@ protected Job setupJob(Job job, String archiveTable, String variantTable) throws FilterList filterList = new FilterList(FilterList.Operator.MUST_PASS_ONE); scan.setFilter(filterList); + scan.addColumn(COLUMN_FAMILY_BYTES, VariantPhoenixSchema.VariantColumn.ALLELES.bytes()); + scan.addColumn(COLUMN_FAMILY_BYTES, VariantPhoenixSchema.VariantColumn.TYPE.bytes()); scan.addColumn(COLUMN_FAMILY_BYTES, VariantPhoenixSchema.VariantColumn.INDEX_NOT_SYNC.bytes()); scan.addColumn(COLUMN_FAMILY_BYTES, VariantPhoenixSchema.VariantColumn.INDEX_UNKNOWN.bytes()); scan.addColumn(COLUMN_FAMILY_BYTES, VariantPhoenixSchema.VariantColumn.INDEX_STUDIES.bytes()); diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/stats/SaturationStatsDriver.java b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/stats/SaturationStatsDriver.java index 100f1f7f73d..0c509a0d7e7 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/stats/SaturationStatsDriver.java +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/stats/SaturationStatsDriver.java @@ -106,6 +106,7 @@ protected Job setupJob(Job job, String archiveTable, String variantTable) throws maxSampleId += maxSampleIdInStudy; } scan.addColumn(GenomeHelper.COLUMN_FAMILY_BYTES, VariantPhoenixSchema.VariantColumn.TYPE.bytes()); + scan.addColumn(GenomeHelper.COLUMN_FAMILY_BYTES, VariantPhoenixSchema.VariantColumn.ALLELES.bytes()); // scan.setFilter(new KeyOnlyFilter()); scan.setFilter( diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/stats/VariantHistogramDriver.java b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/stats/VariantHistogramDriver.java index 306a59faf7b..7c4db8f70d3 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/stats/VariantHistogramDriver.java +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/stats/VariantHistogramDriver.java @@ -76,7 +76,8 @@ protected void parseAndValidateParameters() throws IOException { protected Job setupJob(Job job, String archiveTable, String variantTable) throws IOException { Scan scan = new Scan(); - + scan.addColumn(GenomeHelper.COLUMN_FAMILY_BYTES, VariantPhoenixSchema.VariantColumn.ALLELES.bytes()); + scan.addColumn(GenomeHelper.COLUMN_FAMILY_BYTES, VariantPhoenixSchema.VariantColumn.TYPE.bytes()); for (Integer studyId : getMetadataManager().getStudyIds()) { scan.addColumn(GenomeHelper.COLUMN_FAMILY_BYTES, VariantPhoenixSchema.getStudyColumn(studyId).bytes()); } diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/stats/VariantStatsDriver.java b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/stats/VariantStatsDriver.java index eb76771b159..c1dc34e2e21 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/stats/VariantStatsDriver.java +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/stats/VariantStatsDriver.java @@ -178,6 +178,7 @@ protected Job setupJob(Job job, String archiveTableName, String variantTableName // See #1600 // Add TYPE column to force scan ALL rows to avoid unlikely but possible timeouts fetching new variants scan.addColumn(GenomeHelper.COLUMN_FAMILY_BYTES, VariantPhoenixSchema.VariantColumn.TYPE.bytes()); + scan.addColumn(GenomeHelper.COLUMN_FAMILY_BYTES, VariantPhoenixSchema.VariantColumn.ALLELES.bytes()); // Remove STUDY filter scan.setFilter(null); diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/test/java/org/opencb/opencga/storage/hadoop/variant/HadoopVariantStorageEngineSVTest.java b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/test/java/org/opencb/opencga/storage/hadoop/variant/HadoopVariantStorageEngineSVTest.java index a6f5611df09..fbcbd773477 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/test/java/org/opencb/opencga/storage/hadoop/variant/HadoopVariantStorageEngineSVTest.java +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/test/java/org/opencb/opencga/storage/hadoop/variant/HadoopVariantStorageEngineSVTest.java @@ -16,12 +16,10 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; +import java.util.*; import static org.junit.Assert.assertEquals; +import static org.opencb.opencga.core.api.ParamConstants.OVERWRITE; /** * Created on 26/06/18. @@ -41,6 +39,12 @@ protected void loadFiles() throws Exception { VariantHbaseTestUtils.printVariants(getVariantStorageEngine().getDBAdaptor(), newOutputUri(getTestName().getMethodName())); } + @Test + public void testRecreateSampleIndex() throws Exception { + variantStorageEngine.sampleIndex(studyMetadata.getName(), Collections.singletonList("all"), new QueryOptions(OVERWRITE, true)); + variantStorageEngine.sampleIndex(studyMetadata2.getName(), Collections.singletonList("all"), new QueryOptions(OVERWRITE, true)); + } + @Test public void checkSampleIndex() throws Exception { for (Variant variant : variantStorageEngine.iterable(new VariantQuery() From 84ecdc6324af2ed64512a7d38041a05c4029f974 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacobo=20Coll=20Morag=C3=B3n?= Date: Tue, 14 May 2024 14:24:03 +0100 Subject: [PATCH 72/85] storage: Fix AIOOBE parsing short rowkey #TASK-6005 --- .../variant/adaptors/phoenix/VariantPhoenixKeyFactory.java | 4 +++- .../adaptors/phoenix/VariantPhoenixKeyFactoryTest.java | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/adaptors/phoenix/VariantPhoenixKeyFactory.java b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/adaptors/phoenix/VariantPhoenixKeyFactory.java index f61cfdcc464..9e06ebc4b51 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/adaptors/phoenix/VariantPhoenixKeyFactory.java +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/adaptors/phoenix/VariantPhoenixKeyFactory.java @@ -277,7 +277,9 @@ public static Variant extractVariantFromResult(Result result) { int chrPosSeparator = ArrayUtils.indexOf(variantRowKey, (byte) 0); int referenceOffset = chrPosSeparator + 1 + UINT_SIZE; - if (Bytes.equals(variantRowKey, referenceOffset, HASH_PREFIX_BYTES.length, HASH_PREFIX_BYTES, 0, HASH_PREFIX_BYTES.length)) { + if (variantRowKey.length > (referenceOffset + HASH_PREFIX_BYTES.length) + && Bytes.equals(variantRowKey, referenceOffset, HASH_PREFIX_BYTES.length, + HASH_PREFIX_BYTES, 0, HASH_PREFIX_BYTES.length)) { // The reference and alternate are hashed. // The type and alleles are stored in the result byte[] type = result.getValue(GenomeHelper.COLUMN_FAMILY_BYTES, diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/test/java/org/opencb/opencga/storage/hadoop/variant/adaptors/phoenix/VariantPhoenixKeyFactoryTest.java b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/test/java/org/opencb/opencga/storage/hadoop/variant/adaptors/phoenix/VariantPhoenixKeyFactoryTest.java index 9e03dcca8b2..578ce5df6ca 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/test/java/org/opencb/opencga/storage/hadoop/variant/adaptors/phoenix/VariantPhoenixKeyFactoryTest.java +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/test/java/org/opencb/opencga/storage/hadoop/variant/adaptors/phoenix/VariantPhoenixKeyFactoryTest.java @@ -41,6 +41,7 @@ public void testVariantRowKey() throws Exception { checkVariantRowKeyGeneration(new Variant("5", 21648, "A", "T")); checkVariantRowKeyGeneration(new Variant("5", 21648, "AAAAAA", "T")); checkVariantRowKeyGeneration(new Variant("5", 21648, "A", "")); + checkVariantRowKeyGeneration(new Variant("5", 21648, "", "T")); checkVariantRowKeyGeneration(new Variant("5", 21648, "AAT", "TTT")); checkVariantRowKeyGeneration(new Variant("X", 21648, "", "TTT")); checkVariantRowKeyGeneration(new Variant("MT", 21648, "", "")); From 83c7d2587d80f980c5ab72f9897213b326f3f711 Mon Sep 17 00:00:00 2001 From: JuanfeSanahuja Date: Tue, 14 May 2024 16:45:40 +0200 Subject: [PATCH 73/85] MailUtils: Deleted the footer of the email because it was duplicated #TASK-464 --- .../main/java/org/opencb/opencga/core/common/MailUtils.java | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/opencga-core/src/main/java/org/opencb/opencga/core/common/MailUtils.java b/opencga-core/src/main/java/org/opencb/opencga/core/common/MailUtils.java index 1802d54a642..bf62bb7c09f 100644 --- a/opencga-core/src/main/java/org/opencb/opencga/core/common/MailUtils.java +++ b/opencga-core/src/main/java/org/opencb/opencga/core/common/MailUtils.java @@ -81,11 +81,7 @@ public static String getEmailContent(String userId, String temporaryPassword) { sb.append("If you did not request a password reset, please contact our support team immediately at support@zettagenomics.com.\n\n"); sb.append("Best regards,\n\n"); sb.append("ZettaGenomics Support Team \n\n"); - sb.append("*This email and any attachments are confidential and may contain privileged information " + - "intended solely for the use of the individual or entity to whom they are addressed. " + - "If you have received this email in error, please notify the sender immediately and delete the email" + - " and any attachments from your system. Any unauthorized use, disclosure, distribution, " + - "or copying of this email or its attachments is strictly prohibited.*"); + return sb.toString(); From c6681433f6f36cdc290bcca7334e7ef21fa7f405 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacobo=20Coll=20Morag=C3=B3n?= Date: Wed, 15 May 2024 14:39:50 +0100 Subject: [PATCH 74/85] storage: Fix last split parse at SampleIndexTableRecordReader #TASK-6005 --- .../storage/hadoop/variant/mr/SampleIndexTableRecordReader.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/mr/SampleIndexTableRecordReader.java b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/mr/SampleIndexTableRecordReader.java index 9790f5b99b1..7e747813b0e 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/mr/SampleIndexTableRecordReader.java +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/mr/SampleIndexTableRecordReader.java @@ -198,7 +198,7 @@ public void initialize(InputSplit inputsplit, TaskAttemptContext context) throws stopChr = null; end = Integer.MAX_VALUE; } else { - Pair stopLocus = VariantPhoenixKeyFactory.extractChrPosFromVariantRowKey(firstRow); + Pair stopLocus = VariantPhoenixKeyFactory.extractChrPosFromVariantRowKey(lastRow); stopChr = stopLocus.getFirst(); end = stopLocus.getSecond(); } From f6b73fe2d55a02e2a361d395863d02a3a810ceab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacobo=20Coll=20Morag=C3=B3n?= Date: Wed, 15 May 2024 14:40:04 +0100 Subject: [PATCH 75/85] storage: Fix return annotation from sample data. Fix test. #TASK-6005 --- ...ariantFileIndexerOperationManagerTest.java | 7 +++---- .../opencga/catalog/managers/FileManager.java | 4 ++-- .../sample/HBaseVariantSampleDataManager.java | 19 ++++++++++--------- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/opencga-analysis/src/test/java/org/opencb/opencga/analysis/variant/manager/operations/VariantFileIndexerOperationManagerTest.java b/opencga-analysis/src/test/java/org/opencb/opencga/analysis/variant/manager/operations/VariantFileIndexerOperationManagerTest.java index 8151de1721b..a4fe3f97944 100644 --- a/opencga-analysis/src/test/java/org/opencb/opencga/analysis/variant/manager/operations/VariantFileIndexerOperationManagerTest.java +++ b/opencga-analysis/src/test/java/org/opencb/opencga/analysis/variant/manager/operations/VariantFileIndexerOperationManagerTest.java @@ -26,7 +26,6 @@ import org.mockito.Mockito; import org.opencb.biodata.models.variant.metadata.Aggregation; import org.opencb.biodata.models.variant.metadata.VariantSetStats; -import org.opencb.commons.datastore.core.DataResult; import org.opencb.commons.datastore.core.Event; import org.opencb.commons.datastore.core.Query; import org.opencb.commons.datastore.core.QueryOptions; @@ -43,8 +42,8 @@ import org.opencb.opencga.core.models.file.File; import org.opencb.opencga.core.models.file.FileInternalVariantIndex; import org.opencb.opencga.core.models.file.VariantIndexStatus; -import org.opencb.opencga.core.models.study.Study; import org.opencb.opencga.core.models.operations.variant.VariantIndexParams; +import org.opencb.opencga.core.models.study.Study; import org.opencb.opencga.core.testclassification.duration.MediumTests; import org.opencb.opencga.core.tools.result.ExecutionResult; import org.opencb.opencga.storage.core.StorageEngineFactory; @@ -186,7 +185,7 @@ public void testDeleteIndexedFile() throws Exception { Study study = catalogManager.getFileManager().getStudy(inputFile, sessionId); thrown.expect(CatalogException.class); - thrown.expectMessage("The status is READY"); + thrown.expectMessage("Could not unlink file '" + inputFile.getId() + "'"); catalogManager.getFileManager().unlink(study.getFqn(), inputFile.getId(), sessionId); } @@ -200,7 +199,7 @@ public void testDeleteSampleFromIndexedFile() throws Exception { Query query = new Query(SampleDBAdaptor.QueryParams.ID.key(), inputFile.getSampleIds().get(100)); thrown.expect(CatalogException.class); thrown.expectMessage("Sample associated to the files"); - DataResult delete = catalogManager.getSampleManager().delete(studyFqn, query, null, sessionId); + catalogManager.getSampleManager().delete(studyFqn, query, null, sessionId); } @Test diff --git a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/managers/FileManager.java b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/managers/FileManager.java index 2d411253440..812bdfae0ca 100644 --- a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/managers/FileManager.java +++ b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/managers/FileManager.java @@ -1832,9 +1832,9 @@ public OpenCGAResult unlink(@Nullable String studyId, String fileId, Strin study.getUuid(), auditParams, new AuditRecord.Status(AuditRecord.Status.Result.SUCCESS)); return result; - } catch (CatalogException e) { + } catch (Exception e) { auditManager.audit(userId, Enums.Action.UNLINK, Enums.Resource.FILE, fileId, "", study.getId(), study.getUuid(), - auditParams, new AuditRecord.Status(AuditRecord.Status.Result.ERROR, e.getError())); + auditParams, new AuditRecord.Status(AuditRecord.Status.Result.ERROR, new Error(0, "", e.getMessage()))); throw new CatalogException("Could not unlink file '" + fileId + "'", e); } } diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/adaptors/sample/HBaseVariantSampleDataManager.java b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/adaptors/sample/HBaseVariantSampleDataManager.java index 659e401d88e..31850f1f486 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/adaptors/sample/HBaseVariantSampleDataManager.java +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/adaptors/sample/HBaseVariantSampleDataManager.java @@ -51,7 +51,7 @@ public HBaseVariantSampleDataManager(VariantHadoopDBAdaptor dbAdaptor) { } @Override - protected DataResult getSampleData(Variant variant, String study, QueryOptions options, + protected DataResult getSampleData(Variant inputVariant, String study, QueryOptions options, List includeSamples, Set genotypes, int sampleLimit) { @@ -78,6 +78,7 @@ protected DataResult getSampleData(Variant variant, String study, Query int skip = Math.max(0, options.getInt(QueryOptions.SKIP, 0)); int limit = Math.max(0, options.getInt(QueryOptions.LIMIT, 10)); + byte[] rowKey = VariantPhoenixKeyFactory.generateVariantRowKey(inputVariant); try { List samples = new ArrayList<>(limit); @@ -85,7 +86,7 @@ protected DataResult getSampleData(Variant variant, String study, Query dbAdaptor.getHBaseManager().act(dbAdaptor.getVariantTable(), table -> { // Create one GET for samples - Get get = new Get(VariantPhoenixKeyFactory.generateVariantRowKey(variant)); + Get get = new Get(rowKey); LinkedList filters = new LinkedList<>(); filters.add(new QualifierFilter(CompareFilter.CompareOp.EQUAL, @@ -127,7 +128,7 @@ protected DataResult getSampleData(Variant variant, String study, Query samples.add(sampleColumn.getSampleId()); sampleDataMap.add(sampleColumn); } - }).walk(variant); + }).walk(inputVariant); } }); @@ -136,8 +137,9 @@ protected DataResult getSampleData(Variant variant, String study, Query Set fileIdsFromSampleIds = metadataManager.getFileIdsFromSampleIds(studyId, samples); HBaseToVariantStatsConverter statsConverter = new HBaseToVariantStatsConverter(); List stats = new LinkedList<>(); + Variant variantResult = new Variant(inputVariant.toString()); dbAdaptor.getHBaseManager().act(dbAdaptor.getVariantTable(), table -> { - Get get = new Get(VariantPhoenixKeyFactory.generateVariantRowKey(variant)); + Get get = new Get(rowKey); // Add file columns for (Integer fileId : fileIdsFromSampleIds) { @@ -161,7 +163,7 @@ protected DataResult getSampleData(Variant variant, String study, Query Result result = table.get(get); if (result == null || result.isEmpty()) { - throw VariantQueryException.variantNotFound(variant.toString()); + throw VariantQueryException.variantNotFound(variantResult.toString()); } // Walk row VariantRow.walker(result) @@ -175,9 +177,9 @@ protected DataResult getSampleData(Variant variant, String study, Query }) .onVariantAnnotation(column -> { ImmutableBytesWritable b = column.toBytesWritable(); - variant.setAnnotation(new HBaseToVariantAnnotationConverter().convert(b.get(), b.getOffset(), b.getLength())); + variantResult.setAnnotation(new HBaseToVariantAnnotationConverter().convert(b)); }) - .walk(variant); + .walk(variantResult); }); // Convert to VariantSampleData @@ -193,8 +195,7 @@ protected DataResult getSampleData(Variant variant, String study, Query new ArrayList<>(fileIdsFromSampleIds))) .build()); - Variant variantResult = new Variant(variant.toString()); - variantResult.setId(variant.toString()); + variantResult.setId(inputVariant.toString()); StudyEntry studyEntry = converter.convert(sampleDataMap, filesMap, variantResult, studyId); variantResult.addStudyEntry(studyEntry); From 9c3113196e67024e5b5fd6fac36b76b05aba9bed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacobo=20Coll=20Morag=C3=B3n?= Date: Thu, 16 May 2024 13:09:16 +0100 Subject: [PATCH 76/85] storage: Mark symbolic inversion as supported. #TASK-6240 --- .../src/test/resources/variant-test-sv.vcf | 2 +- .../src/test/resources/variant-test-sv_2.vcf | 2 +- .../HadoopLocalLoadVariantStoragePipeline.java | 7 ++++--- .../hadoop/variant/HadoopVariantStorageEngine.java | 13 +++---------- .../variant/gaps/AbstractFillFromArchiveTask.java | 4 ++-- 5 files changed, 11 insertions(+), 17 deletions(-) diff --git a/opencga-storage/opencga-storage-core/src/test/resources/variant-test-sv.vcf b/opencga-storage/opencga-storage-core/src/test/resources/variant-test-sv.vcf index bce755b9486..9fc4fe9c325 100644 --- a/opencga-storage/opencga-storage-core/src/test/resources/variant-test-sv.vcf +++ b/opencga-storage/opencga-storage-core/src/test/resources/variant-test-sv.vcf @@ -46,7 +46,7 @@ 1 700000 . C . PASS SVTYPE=DEL;END=700297;SVLEN=-297;CIPOS=-22,18;CIEND=-12,32 GT 0/1 0/1 1 800000 . A . PASS SVTYPE=INS;END=800000;SVLEN=6027;CIPOS=-16,22;RIGHT_SVINSSEQ=ACCACACCCACACAACACACA;LEFT_SVINSSEQ=TGTGGTGTGTGTGGTGTG GT 0/1 0/1 1 850000 . A . PASS SVTYPE=INS;END=850000;SVINSSEQ=ACCACACCCACACAACACACAACCACACCCACACAACACACAACCACACCCACACAACACACAACCACACCCACACAACACACAACCACACCCACACAACACACAACCACACCCACACAACACACAACCACACCCACACAACACACAACCACACCCACACAACACACAACCACACCCACACAACACACAACCACACCCACACAACACACAACCACACCCACACAACACACA GT 0/1 0/1 -1 860000 . A . PASS SVTYPE=INS;END=860000;SVLEN=1000 GT 0/1 0/1 +1 860000 . A . PASS SVTYPE=INVERSION;END=870000 GT 0/1 0/1 1 900000 . G . PASS SVTYPE=INS;END=900000;SVLEN=6027;CIPOS=-16,22 GT 0/1 0/1 1 1000000 . A . PASS SVTYPE=DUP;END=1021100;SVLEN=21100;CIPOS=-500,500;CIEND=-500,500 GT 0/1 0/1 1 1100000 . T . PASS SVTYPE=DUP;END=1100076;SVLEN=76;CIPOS=-10,10;CIEND=-10,10 GT 0/1 0/1 diff --git a/opencga-storage/opencga-storage-core/src/test/resources/variant-test-sv_2.vcf b/opencga-storage/opencga-storage-core/src/test/resources/variant-test-sv_2.vcf index c6e2b9176e4..32ad6f4c4f0 100644 --- a/opencga-storage/opencga-storage-core/src/test/resources/variant-test-sv_2.vcf +++ b/opencga-storage/opencga-storage-core/src/test/resources/variant-test-sv_2.vcf @@ -46,7 +46,7 @@ 1 700010 . T C . PASS . GT 0/1 0/1 1 800000 . A . PASS SVTYPE=INS;END=800000;SVLEN=6027;CIPOS=-16,22;RIGHT_SVINSSEQ=TGTGGTGTGTGTGGTGTG;LEFT_SVINSSEQ=ACCACACCCACACAACACACA GT 0/1 0/1 1 850000 . A . PASS SVTYPE=INS;END=850000;SVINSSEQ=TGTGGTGTGTGTGGTGTGTGTGGTGTGTGTGGTGTGTGTGGTGTGTGTGGTGTGTGTGGTGTGTGTGGTGTGTGTGGTGTGTGTGGTGTGTGTGGTGTGTGTGGTGTGTGTGGTGTGTGTGGTGTGTGTGGTGTGTGTGGTGTG GT 0/1 0/1 -1 860000 . A . PASS SVTYPE=INS;END=860000;SVLEN=1000 GT 0/1 0/1 +1 860000 . A . PASS SVTYPE=INVERSION;END=870000 GT 0/1 0/1 1 900000 . G . PASS SVTYPE=INS;END=900000;SVLEN=6027;CIPOS=-16,22 GT 0/1 0/1 1 1000000 . A . PASS SVTYPE=DUP;END=1021100;SVLEN=21100;CIPOS=-500,500;CIEND=-500,500 GT 0/1 0/1 1 1100000 . T . PASS SVTYPE=DUP;END=1100076;SVLEN=76;CIPOS=-10,10;CIEND=-10,10 GT 0/1 0/1 diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/HadoopLocalLoadVariantStoragePipeline.java b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/HadoopLocalLoadVariantStoragePipeline.java index 5c3d0e7a0d1..4fdeca66595 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/HadoopLocalLoadVariantStoragePipeline.java +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/HadoopLocalLoadVariantStoragePipeline.java @@ -70,6 +70,7 @@ import static org.opencb.opencga.storage.core.metadata.models.TaskMetadata.Type; import static org.opencb.opencga.storage.core.variant.VariantStorageOptions.*; import static org.opencb.opencga.storage.hadoop.variant.HadoopVariantStorageEngine.TARGET_VARIANT_TYPE_SET; +import static org.opencb.opencga.storage.hadoop.variant.HadoopVariantStorageEngine.UNSUPPORTED_VARIANT_TYPE_SET; import static org.opencb.opencga.storage.hadoop.variant.HadoopVariantStorageOptions.*; /** @@ -390,13 +391,13 @@ protected void loadFromAvroWithArchive(URI input, URI outdir, ArchiveTableHelper throw new StorageEngineException("Error loading file " + input, e); } - logLoadResults(variantReader.getVariantFileMetadata(), resolver, hadoopDBWriter); if (sampleIndexDBLoader != null) { // Update list of loaded genotypes this.loadedGenotypes = sampleIndexDBLoader.getLoadedGenotypes(); this.sampleIndexVersion = sampleIndexDBLoader.getSampleIndexVersion(); this.largestVariantLength = largestVariantTask.getMaxLength(); } + logLoadResults(variantReader.getVariantFileMetadata(), resolver, hadoopDBWriter); } protected void loadFromAvroWithoutArchive(URI input, URI outdir, ArchiveTableHelper helper, ProgressLogger progressLogger) @@ -438,13 +439,13 @@ protected void loadFromAvroWithoutArchive(URI input, URI outdir, ArchiveTableHel throw new StorageEngineException("Error loading file " + input, e); } - logLoadResults(variantReader.getVariantFileMetadata(), resolver, hadoopDBWriter); if (sampleIndexDBLoader != null) { // Update list of loaded genotypes this.loadedGenotypes = sampleIndexDBLoader.getLoadedGenotypes(); this.sampleIndexVersion = sampleIndexDBLoader.getSampleIndexVersion(); this.largestVariantLength = largestVariantTask.getMaxLength(); } + logLoadResults(variantReader.getVariantFileMetadata(), resolver, hadoopDBWriter); } private void logLoadResults(VariantFileMetadata variantFileMetadata, @@ -490,7 +491,7 @@ private void logLoadResults(VariantFileMetadata variantFileMetadata, int duplica if (skipped > 0) { logger.info("There were " + skipped + " skipped variants"); for (VariantType type : VariantType.values()) { - if (!TARGET_VARIANT_TYPE_SET.contains(type)) { + if (UNSUPPORTED_VARIANT_TYPE_SET.contains(type)) { Long countByType = variantFileMetadata.getStats().getTypeCount().get(type.toString()); if (countByType != null && countByType > 0) { logger.info(" * Of which " + countByType + " are " + type.toString() + " variants."); diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/HadoopVariantStorageEngine.java b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/HadoopVariantStorageEngine.java index 65927c62fb2..18c0f364329 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/HadoopVariantStorageEngine.java +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/HadoopVariantStorageEngine.java @@ -121,17 +121,10 @@ public class HadoopVariantStorageEngine extends VariantStorageEngine implements Configurable { public static final String STORAGE_ENGINE_ID = "hadoop"; - public static final EnumSet TARGET_VARIANT_TYPE_SET = EnumSet.of( - VariantType.SNV, VariantType.SNP, - VariantType.INDEL, - VariantType.MNV, VariantType.MNP, - VariantType.INSERTION, VariantType.DELETION, - VariantType.CNV, - VariantType.COPY_NUMBER, VariantType.COPY_NUMBER_LOSS, VariantType.COPY_NUMBER_GAIN, - VariantType.DUPLICATION, VariantType.TANDEM_DUPLICATION, VariantType.TRANSLOCATION, - VariantType.BREAKEND, - VariantType.SV, VariantType.SYMBOLIC + public static final EnumSet UNSUPPORTED_VARIANT_TYPE_SET = EnumSet.of( + VariantType.NO_VARIATION, VariantType.MIXED ); + public static final EnumSet TARGET_VARIANT_TYPE_SET = EnumSet.complementOf(UNSUPPORTED_VARIANT_TYPE_SET); public static final String FILE_ID = "fileId"; public static final String STUDY_ID = "studyId"; diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/gaps/AbstractFillFromArchiveTask.java b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/gaps/AbstractFillFromArchiveTask.java index d218cf0a470..1e0a01f89b4 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/gaps/AbstractFillFromArchiveTask.java +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/src/main/java/org/opencb/opencga/storage/hadoop/variant/gaps/AbstractFillFromArchiveTask.java @@ -32,7 +32,7 @@ import java.util.*; import java.util.concurrent.TimeUnit; -import static org.opencb.opencga.storage.hadoop.variant.HadoopVariantStorageEngine.TARGET_VARIANT_TYPE_SET; +import static org.opencb.opencga.storage.hadoop.variant.HadoopVariantStorageEngine.UNSUPPORTED_VARIANT_TYPE_SET; /** * Created on 31/10/17. @@ -348,7 +348,7 @@ protected static Scan buildScan(String regionStr, int fileId, Configuration conf protected static boolean isVariantAlreadyLoaded(VcfSliceProtos.VcfSlice slice, VcfSliceProtos.VcfRecord vcfRecord) { VariantType variantType = VcfRecordProtoToVariantConverter.getVariantType(vcfRecord.getType()); // The variant is not loaded if is a NO_VARIATION (fast check first) - if (!TARGET_VARIANT_TYPE_SET.contains(variantType)) { + if (UNSUPPORTED_VARIANT_TYPE_SET.contains(variantType)) { return false; } From 8eb0843b2a168118cf179ea5522f3cd79402c35e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacobo=20Coll=20Morag=C3=B3n?= Date: Fri, 17 May 2024 15:01:32 +0100 Subject: [PATCH 77/85] app: Fix migration illegal_concurrent_file_loadings. #TASK-6078 --- .../DetectIllegalConcurrentFileLoadingsMigration.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/opencga-app/src/main/java/org/opencb/opencga/app/migrations/v2_12_5/storage/DetectIllegalConcurrentFileLoadingsMigration.java b/opencga-app/src/main/java/org/opencb/opencga/app/migrations/v2_12_5/storage/DetectIllegalConcurrentFileLoadingsMigration.java index d64a3163715..c4ca5d66734 100644 --- a/opencga-app/src/main/java/org/opencb/opencga/app/migrations/v2_12_5/storage/DetectIllegalConcurrentFileLoadingsMigration.java +++ b/opencga-app/src/main/java/org/opencb/opencga/app/migrations/v2_12_5/storage/DetectIllegalConcurrentFileLoadingsMigration.java @@ -22,6 +22,7 @@ import org.opencb.opencga.storage.core.variant.adaptors.VariantField; import org.opencb.opencga.storage.core.variant.adaptors.VariantQuery; +import java.nio.file.Paths; import java.time.Instant; import java.util.*; import java.util.stream.Collectors; @@ -244,7 +245,12 @@ private void checkStudy(VariantStorageEngine engine, String study) throws Storag fileMetadata.getAttributes().put("TASK-6078", thisEvent.append("oldStatus", oldStatus)); } }).getPath(); - catalogManager.getFileManager().update(study, filePath, + String fileUri = Paths.get(filePath).toUri().toString(); + Query query = new Query(FileDBAdaptor.QueryParams.URI.key(), fileUri); + String catalogFileId = catalogManager.getFileManager() + .search(study, query, new QueryOptions(QueryOptions.INCLUDE, FileDBAdaptor.QueryParams.ID.key()), token) + .first().getId(); + catalogManager.getFileManager().update(study, catalogFileId, new FileUpdateParams().setAttributes(new ObjectMap("TASK-6078", thisEvent)), QueryOptions.empty(), token); } for (Integer sampleId : invalidSamples) { From 214f963759c442b1a95f932d657a4aae2fe49f01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacobo=20Coll=20Morag=C3=B3n?= Date: Tue, 21 May 2024 09:45:23 +0100 Subject: [PATCH 78/85] core: Register new index status INVALID in catalog #TASK-6078 --- .../org/opencb/opencga/core/models/common/IndexStatus.java | 4 +++- .../opencb/opencga/core/models/file/VariantIndexStatus.java | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/opencga-core/src/main/java/org/opencb/opencga/core/models/common/IndexStatus.java b/opencga-core/src/main/java/org/opencb/opencga/core/models/common/IndexStatus.java index 5a1518440ab..83836d0f7d4 100644 --- a/opencga-core/src/main/java/org/opencb/opencga/core/models/common/IndexStatus.java +++ b/opencga-core/src/main/java/org/opencb/opencga/core/models/common/IndexStatus.java @@ -13,8 +13,9 @@ public class IndexStatus extends InternalStatus { */ public static final String NONE = "NONE"; public static final String INDEXING = "INDEXING"; + public static final String INVALID = "INVALID"; - public static final List STATUS_LIST = Arrays.asList(READY, DELETED, NONE, INDEXING); + public static final List STATUS_LIST = Arrays.asList(READY, DELETED, NONE, INDEXING, INVALID); public IndexStatus(String status, String message) { if (isValid(status)) { @@ -50,6 +51,7 @@ public static boolean isValid(String status) { return status != null && (status.equals(READY) || status.equals(DELETED) + || status.equals(INVALID) || status.equals(NONE) || status.equals(INDEXING)); } diff --git a/opencga-core/src/main/java/org/opencb/opencga/core/models/file/VariantIndexStatus.java b/opencga-core/src/main/java/org/opencb/opencga/core/models/file/VariantIndexStatus.java index 3dbe5f21f7d..a6592c369bf 100644 --- a/opencga-core/src/main/java/org/opencb/opencga/core/models/file/VariantIndexStatus.java +++ b/opencga-core/src/main/java/org/opencb/opencga/core/models/file/VariantIndexStatus.java @@ -19,7 +19,8 @@ public class VariantIndexStatus extends IndexStatus { public static final String TRANSFORMED = "TRANSFORMED"; public static final String LOADING = "LOADING"; - public static final List STATUS_LIST = Arrays.asList(READY, DELETED, NONE, TRANSFORMED, TRANSFORMING, LOADING, INDEXING); + public static final List STATUS_LIST = Arrays.asList(READY, DELETED, NONE, TRANSFORMED, TRANSFORMING, LOADING, INDEXING, + INVALID); public VariantIndexStatus(String status, String message) { if (isValid(status)) { @@ -56,6 +57,7 @@ public static boolean isValid(String status) { && (status.equals(READY) || status.equals(DELETED) || status.equals(NONE) + || status.equals(INVALID) || status.equals(TRANSFORMED) || status.equals(TRANSFORMING) || status.equals(LOADING) From 17129ab9664d59b938d313fc6aab488abfbb410b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacobo=20Coll=20Morag=C3=B3n?= Date: Tue, 21 May 2024 09:47:51 +0100 Subject: [PATCH 79/85] app: Synchronize storage-catalog status after running migration. #TASK-6078 --- ...llegalConcurrentFileLoadingsMigration.java | 151 +++++++++++++----- 1 file changed, 107 insertions(+), 44 deletions(-) diff --git a/opencga-app/src/main/java/org/opencb/opencga/app/migrations/v2_12_5/storage/DetectIllegalConcurrentFileLoadingsMigration.java b/opencga-app/src/main/java/org/opencb/opencga/app/migrations/v2_12_5/storage/DetectIllegalConcurrentFileLoadingsMigration.java index c4ca5d66734..22a4942b651 100644 --- a/opencga-app/src/main/java/org/opencb/opencga/app/migrations/v2_12_5/storage/DetectIllegalConcurrentFileLoadingsMigration.java +++ b/opencga-app/src/main/java/org/opencb/opencga/app/migrations/v2_12_5/storage/DetectIllegalConcurrentFileLoadingsMigration.java @@ -3,14 +3,18 @@ import org.opencb.commons.datastore.core.ObjectMap; import org.opencb.commons.datastore.core.Query; import org.opencb.commons.datastore.core.QueryOptions; +import org.opencb.opencga.analysis.variant.metadata.CatalogStorageMetadataSynchronizer; import org.opencb.opencga.app.migrations.StorageMigrationTool; import org.opencb.opencga.catalog.db.api.FileDBAdaptor; import org.opencb.opencga.catalog.exceptions.CatalogException; import org.opencb.opencga.catalog.migration.Migration; import org.opencb.opencga.core.common.TimeUtils; import org.opencb.opencga.core.common.UriUtils; +import org.opencb.opencga.core.models.common.IndexStatus; import org.opencb.opencga.core.models.file.File; +import org.opencb.opencga.core.models.file.FileInternalVariantIndex; import org.opencb.opencga.core.models.file.FileUpdateParams; +import org.opencb.opencga.core.models.file.VariantIndexStatus; import org.opencb.opencga.core.models.sample.SampleUpdateParams; import org.opencb.opencga.storage.core.exceptions.StorageEngineException; import org.opencb.opencga.storage.core.metadata.VariantStorageMetadataManager; @@ -53,6 +57,7 @@ protected void run() throws Exception { private void checkStudy(VariantStorageEngine engine, String study) throws StorageEngineException, CatalogException { VariantStorageMetadataManager metadataManager = engine.getMetadataManager(); + boolean repeatMigration = params.getBoolean("repeat-migration"); logger.info("Checking study '{}'", study); int studyId = metadataManager.getStudyId(study); @@ -217,60 +222,118 @@ private void checkStudy(VariantStorageEngine engine, String study) throws Storag .append("dateStr", TimeUtils.getTime()) .append("date", Date.from(Instant.now())); for (Integer sampleId : invalidSampleIndexes) { - ObjectMap thisEvent = new ObjectMap(event); - String sampleName = metadataManager.updateSampleMetadata(studyId, sampleId, sampleMetadata -> { - if (sampleMetadata.getAttributes().containsKey("TASK-6078")) { - logger.info("Sample '{}'({}) already has the attribute 'TASK-6078'. Skip", sampleMetadata.getName(), sampleMetadata.getId()); - } else { - Map oldStatus = new HashMap<>(sampleMetadata.getStatus()); - for (Integer sampleIndexVersion : sampleMetadata.getSampleIndexVersions()) { - sampleMetadata.setSampleIndexStatus(TaskMetadata.Status.NONE, sampleIndexVersion); - } - sampleMetadata.getAttributes().put("TASK-6078", thisEvent.append("oldStatus", oldStatus)); - } - }).getName(); - catalogManager.getSampleManager().update(study, sampleName, - new SampleUpdateParams().setAttributes(new ObjectMap("TASK-6078", thisEvent)), QueryOptions.empty(), token); + invalidateSecondarySampleIndex(study, sampleId, event, metadataManager, studyId, repeatMigration); } Set invalidSamples = new HashSet<>(); for (Integer fileId : invalidFiles) { - ObjectMap thisEvent = new ObjectMap(event); - String filePath = metadataManager.updateFileMetadata(studyId, fileId, fileMetadata -> { - invalidSamples.addAll(fileMetadata.getSamples()); - if (fileMetadata.getAttributes().containsKey("TASK-6078")) { - logger.info("File '{}'({}) already has the attribute 'TASK-6078'. Skip", fileMetadata.getName(), fileMetadata.getId()); - } else { - Map oldStatus = new HashMap<>(fileMetadata.getStatus()); - fileMetadata.setIndexStatus(TaskMetadata.Status.INVALID); - fileMetadata.getAttributes().put("TASK-6078", thisEvent.append("oldStatus", oldStatus)); - } - }).getPath(); - String fileUri = Paths.get(filePath).toUri().toString(); - Query query = new Query(FileDBAdaptor.QueryParams.URI.key(), fileUri); - String catalogFileId = catalogManager.getFileManager() - .search(study, query, new QueryOptions(QueryOptions.INCLUDE, FileDBAdaptor.QueryParams.ID.key()), token) - .first().getId(); - catalogManager.getFileManager().update(study, catalogFileId, - new FileUpdateParams().setAttributes(new ObjectMap("TASK-6078", thisEvent)), QueryOptions.empty(), token); + invalidateFileIndex(study, fileId, event, metadataManager, studyId, invalidSamples, repeatMigration); } for (Integer sampleId : invalidSamples) { - ObjectMap thisEvent = new ObjectMap(event); - String sampleName = metadataManager.updateSampleMetadata(studyId, sampleId, sampleMetadata -> { - if (sampleMetadata.getAttributes().containsKey("TASK-6078")) { - logger.info("Sample '{}'({}) already has the attribute 'TASK-6078'. Skip", sampleMetadata.getName(), sampleMetadata.getId()); - } else { - Map oldStatus = new HashMap<>(sampleMetadata.getStatus()); - sampleMetadata.setIndexStatus(TaskMetadata.Status.INVALID); - sampleMetadata.getAttributes().put("TASK-6078", thisEvent.append("oldStatus", oldStatus)); - } - }).getName(); - catalogManager.getSampleManager().update(study, sampleName, - new SampleUpdateParams().setAttributes(new ObjectMap("TASK-6078", thisEvent)), QueryOptions.empty(), token); + invalidateSampleIndex(study, sampleId, event, metadataManager, studyId, repeatMigration); } + + Set allSampleIds = new HashSet<>(); + allSampleIds.addAll(affectedSamples); + allSampleIds.addAll(invalidSamples); + List allSampleNames = allSampleIds.stream() + .map(sampleId -> metadataManager.getSampleName(studyId, sampleId)) + .collect(Collectors.toList()); + + if (!allSampleNames.isEmpty()) { + new CatalogStorageMetadataSynchronizer(catalogManager, metadataManager) + .synchronizeCatalogSamplesFromStorage(study, allSampleNames, token); + } + } } } + private void invalidateFileIndex(String study, Integer fileId, ObjectMap event, VariantStorageMetadataManager metadataManager, int studyId, Set invalidSamples, boolean repeatMigration) throws StorageEngineException, CatalogException { + ObjectMap thisEvent = new ObjectMap(event); + String filePath = metadataManager.updateFileMetadata(studyId, fileId, fileMetadata -> { + invalidSamples.addAll(fileMetadata.getSamples()); + if (fileMetadata.getAttributes().containsKey("TASK-6078") && !repeatMigration) { + logger.info("File '{}'({}) already has the attribute 'TASK-6078'. Skip", + fileMetadata.getName(), fileMetadata.getId()); + } else { + Map oldStatus = new HashMap<>(fileMetadata.getStatus()); + fileMetadata.setIndexStatus(TaskMetadata.Status.INVALID); + fileMetadata.getAttributes().put("TASK-6078", thisEvent.append("oldStatus", oldStatus)); + } + }).getPath(); + String fileUri = Paths.get(filePath).toUri().toString(); + Query query = new Query(FileDBAdaptor.QueryParams.URI.key(), fileUri); + File file = catalogManager.getFileManager() + .search(study, query, new QueryOptions(), token) + .first(); + catalogManager.getFileManager().update(study, file.getId(), + new FileUpdateParams().setAttributes(new ObjectMap("TASK-6078", thisEvent)), QueryOptions.empty(), token); + catalogManager.getFileManager().updateFileInternalVariantIndex(file, new FileInternalVariantIndex() + .setStatus(new VariantIndexStatus(IndexStatus.INVALID, "Invalid status - TASK-6078 - affected_invalid_sample - " + + "File must be deleted and then indexed")), token); + } + + private void invalidateSecondarySampleIndex(String study, Integer sampleId, ObjectMap event, VariantStorageMetadataManager metadataManager, int studyId, boolean repeatMigration) throws StorageEngineException, CatalogException { + ObjectMap thisEvent = new ObjectMap(event); + String sampleName = metadataManager.updateSampleMetadata(studyId, sampleId, sampleMetadata -> { + if (sampleMetadata.getAttributes().containsKey("TASK-6078") && !repeatMigration) { + logger.info("Sample '{}'({}) already has the attribute 'TASK-6078'. Skip", + sampleMetadata.getName(), sampleMetadata.getId()); + } else { + Map oldStatus = new HashMap<>(sampleMetadata.getStatus()); + Map oldAttributes = new HashMap<>(sampleMetadata.getAttributes()); + + for (Integer v : sampleMetadata.getSampleIndexVersions()) { + sampleMetadata.setSampleIndexStatus(TaskMetadata.Status.NONE, v); + } + for (Integer v : sampleMetadata.getSampleIndexAnnotationVersions()) { + sampleMetadata.setSampleIndexAnnotationStatus(TaskMetadata.Status.NONE, v); + } + for (Integer v : sampleMetadata.getFamilyIndexVersions()) { + sampleMetadata.setFamilyIndexStatus(TaskMetadata.Status.NONE, v); + } + + sampleMetadata.setIndexStatus(TaskMetadata.Status.INVALID); + thisEvent.append("oldStatus", oldStatus); + thisEvent.append("oldAttributes", oldAttributes); + thisEvent.append("newStatus", sampleMetadata.getStatus()); + sampleMetadata.getAttributes().put("TASK-6078", thisEvent); + } + }).getName(); + catalogManager.getSampleManager().update(study, sampleName, + new SampleUpdateParams().setAttributes(new ObjectMap("TASK-6078", thisEvent)), QueryOptions.empty(), token); + } + + private void invalidateSampleIndex(String study, Integer sampleId, ObjectMap event, VariantStorageMetadataManager metadataManager, int studyId, boolean repeatMigration) throws StorageEngineException, CatalogException { + ObjectMap thisEvent = new ObjectMap(event); + String sampleName = metadataManager.updateSampleMetadata(studyId, sampleId, sampleMetadata -> { + if (sampleMetadata.getAttributes().containsKey("TASK-6078") && !repeatMigration) { + logger.info("Sample '{}'({}) already has the attribute 'TASK-6078'. Skip", + sampleMetadata.getName(), sampleMetadata.getId()); + } else { + Map oldStatus = new HashMap<>(sampleMetadata.getStatus()); + Map oldAttributes = new HashMap<>(sampleMetadata.getAttributes()); + sampleMetadata.setIndexStatus(TaskMetadata.Status.INVALID); + + for (Integer v : sampleMetadata.getSampleIndexVersions()) { + sampleMetadata.setSampleIndexStatus(TaskMetadata.Status.NONE, v); + } + for (Integer v : sampleMetadata.getSampleIndexAnnotationVersions()) { + sampleMetadata.setSampleIndexAnnotationStatus(TaskMetadata.Status.NONE, v); + } + for (Integer v : sampleMetadata.getFamilyIndexVersions()) { + sampleMetadata.setFamilyIndexStatus(TaskMetadata.Status.NONE, v); + } + thisEvent.append("oldStatus", oldStatus); + thisEvent.append("oldAttributes", oldAttributes); + thisEvent.append("newStatus", sampleMetadata.getStatus()); + sampleMetadata.getAttributes().put("TASK-6078", thisEvent); + } + }).getName(); + catalogManager.getSampleManager().update(study, sampleName, + new SampleUpdateParams().setAttributes(new ObjectMap("TASK-6078", thisEvent)), QueryOptions.empty(), token); + } + private Set> getFileWithSharedSamples(VariantStorageEngine engine, int studyId) throws StorageEngineException { VariantStorageMetadataManager metadataManager = engine.getMetadataManager(); From 53b67f0c82d72a886bb25199606f4ac8bace1af1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacobo=20Coll=20Morag=C3=B3n?= Date: Tue, 21 May 2024 09:48:02 +0100 Subject: [PATCH 80/85] analysis: Allow force variant file remove. #TASK-6078 --- .../operations/VariantDeleteOperationManager.java | 12 +++++++++++- .../operations/VariantFileDeleteOperationTool.java | 1 + .../operations/variant/VariantFileDeleteParams.java | 10 ++++++++++ 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/opencga-analysis/src/main/java/org/opencb/opencga/analysis/variant/manager/operations/VariantDeleteOperationManager.java b/opencga-analysis/src/main/java/org/opencb/opencga/analysis/variant/manager/operations/VariantDeleteOperationManager.java index 550c00b027a..882240d2865 100644 --- a/opencga-analysis/src/main/java/org/opencb/opencga/analysis/variant/manager/operations/VariantDeleteOperationManager.java +++ b/opencga-analysis/src/main/java/org/opencb/opencga/analysis/variant/manager/operations/VariantDeleteOperationManager.java @@ -26,6 +26,7 @@ import org.opencb.opencga.storage.core.metadata.models.StudyMetadata; import org.opencb.opencga.storage.core.metadata.models.TaskMetadata; import org.opencb.opencga.storage.core.variant.VariantStorageEngine; +import org.opencb.opencga.storage.core.variant.VariantStorageOptions; import java.net.URI; import java.util.ArrayList; @@ -52,6 +53,7 @@ public void removeStudy(String study, URI outdir, String token) throws CatalogEx public void removeFile(String study, List inputFiles, URI outdir, String token) throws CatalogException, StorageEngineException { // Update study metadata BEFORE executing the operation and fetching files from Catalog + boolean force = variantStorageEngine.getOptions().getBoolean(VariantStorageOptions.FORCE.key()); StudyMetadata studyMetadata = synchronizeCatalogStudyFromStorage(study, token, true); List fileNames = new ArrayList<>(); @@ -62,7 +64,15 @@ public void removeFile(String study, List inputFiles, URI outdir, String if (!catalogIndexStatus.equals(VariantIndexStatus.READY)) { // Might be partially loaded in VariantStorage. Check FileMetadata FileMetadata fileMetadata = variantStorageEngine.getMetadataManager().getFileMetadata(studyMetadata.getId(), fileStr); - if (fileMetadata == null || fileMetadata.getIndexStatus() != TaskMetadata.Status.NONE) { + boolean canBeRemoved; + if (force) { + // When forcing remove, just require the file to be registered in the storage + canBeRemoved = fileMetadata != null; + } else { + // Otherwise, require the file to be in status NONE + canBeRemoved = fileMetadata != null && fileMetadata.getIndexStatus() != TaskMetadata.Status.NONE; + } + if (!canBeRemoved) { throw new CatalogException("Unable to remove variants from file " + file.getName() + ". " + "IndexStatus = " + catalogIndexStatus); } diff --git a/opencga-analysis/src/main/java/org/opencb/opencga/analysis/variant/operations/VariantFileDeleteOperationTool.java b/opencga-analysis/src/main/java/org/opencb/opencga/analysis/variant/operations/VariantFileDeleteOperationTool.java index 8a321c24ff3..85b4f8b1b48 100644 --- a/opencga-analysis/src/main/java/org/opencb/opencga/analysis/variant/operations/VariantFileDeleteOperationTool.java +++ b/opencga-analysis/src/main/java/org/opencb/opencga/analysis/variant/operations/VariantFileDeleteOperationTool.java @@ -55,6 +55,7 @@ protected void check() throws Exception { throw new ToolException("Missing file/s"); } params.put(VariantStorageOptions.RESUME.key(), variantFileDeleteParams.isResume()); + params.put(VariantStorageOptions.FORCE.key(), variantFileDeleteParams.isForce()); } @Override diff --git a/opencga-core/src/main/java/org/opencb/opencga/core/models/operations/variant/VariantFileDeleteParams.java b/opencga-core/src/main/java/org/opencb/opencga/core/models/operations/variant/VariantFileDeleteParams.java index 1a44f224af7..85ba64ce78c 100644 --- a/opencga-core/src/main/java/org/opencb/opencga/core/models/operations/variant/VariantFileDeleteParams.java +++ b/opencga-core/src/main/java/org/opencb/opencga/core/models/operations/variant/VariantFileDeleteParams.java @@ -34,6 +34,7 @@ public VariantFileDeleteParams(List file, boolean resume) { private List file; private boolean resume; + private boolean force; public List getFile() { return file; @@ -52,4 +53,13 @@ public VariantFileDeleteParams setResume(boolean resume) { this.resume = resume; return this; } + + public boolean isForce() { + return force; + } + + public VariantFileDeleteParams setForce(boolean force) { + this.force = force; + return this; + } } From bdfa4d61462fe4314903c34ca6ab34dceee1aa46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacobo=20Coll=20Morag=C3=B3n?= Date: Fri, 24 May 2024 09:45:23 +0100 Subject: [PATCH 81/85] app: Remove "manual=true" from migration illegal_concurrent_file_loadings #TASK-6305 --- .../storage/DetectIllegalConcurrentFileLoadingsMigration.java | 1 - 1 file changed, 1 deletion(-) diff --git a/opencga-app/src/main/java/org/opencb/opencga/app/migrations/v2_12_5/storage/DetectIllegalConcurrentFileLoadingsMigration.java b/opencga-app/src/main/java/org/opencb/opencga/app/migrations/v2_12_5/storage/DetectIllegalConcurrentFileLoadingsMigration.java index 22a4942b651..c407cd82bbd 100644 --- a/opencga-app/src/main/java/org/opencb/opencga/app/migrations/v2_12_5/storage/DetectIllegalConcurrentFileLoadingsMigration.java +++ b/opencga-app/src/main/java/org/opencb/opencga/app/migrations/v2_12_5/storage/DetectIllegalConcurrentFileLoadingsMigration.java @@ -34,7 +34,6 @@ @Migration(id = "illegal_concurrent_file_loadings" , description = "Detect illegal concurrent file loadings and fix them by setting 'status' to 'INVALID' or 'READY'", version = "2.12.5", - manual = true, domain = Migration.MigrationDomain.STORAGE, language = Migration.MigrationLanguage.JAVA, date = 20240424 From 373fe21f4b61f326d9fb975d85e8b823c1b18e9b Mon Sep 17 00:00:00 2001 From: JuanfeSanahuja Date: Thu, 30 May 2024 18:06:51 +0200 Subject: [PATCH 82/85] cicd: Update action version to test for compatibility with test and release process #TASK-6264 --- .github/workflows/check-junit-test.yml | 2 +- .github/workflows/manual-deploy-docker.yml | 6 +++--- .github/workflows/manual-deploy-ext-tools.yml | 6 +++--- .github/workflows/test-analysis.yml | 8 ++++---- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/.github/workflows/check-junit-test.yml b/.github/workflows/check-junit-test.yml index 4331f156cf5..58bbc6fe538 100644 --- a/.github/workflows/check-junit-test.yml +++ b/.github/workflows/check-junit-test.yml @@ -27,7 +27,7 @@ jobs: outputs: profiles: ${{ steps.getter.outputs.profiles }} steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: '10' - name: Building string profiles to run diff --git a/.github/workflows/manual-deploy-docker.yml b/.github/workflows/manual-deploy-docker.yml index 9a276c7d9b0..f4c79f4c241 100644 --- a/.github/workflows/manual-deploy-docker.yml +++ b/.github/workflows/manual-deploy-docker.yml @@ -18,12 +18,12 @@ jobs: outputs: version: ${{ steps.get_project_version.outputs.version }} steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: '10' ref: "${{ inputs.branch }}" - name: Set up JDK 8 - uses: actions/setup-java@v3 + uses: actions/setup-java@v4 with: distribution: 'temurin' java-version: '8' @@ -36,7 +36,7 @@ jobs: fi - name: Maven Build (skip tests) run: mvn -T 2 clean install -DskipTests -P storage-hadoop,hdp3.1,RClient,opencga-storage-hadoop-deps -Dopencga.war.name=opencga -Dcheckstyle.skip -pl '!:opencga-storage-hadoop-deps-emr6.1,!:opencga-storage-hadoop-deps-hdp2.6' - - uses: actions/upload-artifact@v3 + - uses: actions/upload-artifact@v4 with: name: build-folder path: build diff --git a/.github/workflows/manual-deploy-ext-tools.yml b/.github/workflows/manual-deploy-ext-tools.yml index 5a10146128a..f64e58cbb10 100644 --- a/.github/workflows/manual-deploy-ext-tools.yml +++ b/.github/workflows/manual-deploy-ext-tools.yml @@ -18,12 +18,12 @@ jobs: outputs: version: ${{ steps.get_project_version.outputs.version }} steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: '10' ref: "${{ inputs.branch }}" - name: Set up JDK 8 - uses: actions/setup-java@v3 + uses: actions/setup-java@v4 with: distribution: 'temurin' java-version: '8' @@ -36,7 +36,7 @@ jobs: fi - name: Maven Build (skip tests) run: mvn -T 2 clean install -DskipTests - - uses: actions/upload-artifact@v3 + - uses: actions/upload-artifact@v4 with: name: build-folder path: build diff --git a/.github/workflows/test-analysis.yml b/.github/workflows/test-analysis.yml index 6a83e6e556c..ccb848d11ec 100644 --- a/.github/workflows/test-analysis.yml +++ b/.github/workflows/test-analysis.yml @@ -20,11 +20,11 @@ jobs: name: Execute Sonar Analysis runs-on: ubuntu-22.04 steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: '0' - name: Set up JDK 11 - uses: actions/setup-java@v3 + uses: actions/setup-java@v4 with: distribution: 'temurin' java-version: '17' @@ -47,11 +47,11 @@ jobs: name: Execute JUnit and Jacoco tests runs-on: ubuntu-22.04 steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: '0' - name: Set up JDK 8 - uses: actions/setup-java@v3 + uses: actions/setup-java@v4 with: distribution: 'temurin' java-version: '8' From e5dd72f1dfd616beeefa8f6847fc5ef9452a39f0 Mon Sep 17 00:00:00 2001 From: JuanfeSanahuja Date: Tue, 4 Jun 2024 12:30:18 +0200 Subject: [PATCH 83/85] Prepare release 2.12.5 --- opencga-analysis/pom.xml | 2 +- opencga-app/pom.xml | 2 +- opencga-catalog/pom.xml | 2 +- opencga-client/pom.xml | 2 +- opencga-clinical/pom.xml | 2 +- opencga-core/pom.xml | 2 +- opencga-master/pom.xml | 2 +- opencga-server/pom.xml | 2 +- opencga-storage/opencga-storage-app/pom.xml | 2 +- opencga-storage/opencga-storage-benchmark/pom.xml | 2 +- opencga-storage/opencga-storage-core/pom.xml | 2 +- .../opencga-storage-hadoop-core/pom.xml | 2 +- .../opencga-storage-hadoop-deps-emr6.1/pom.xml | 2 +- .../opencga-storage-hadoop-deps-hdp2.6/pom.xml | 2 +- .../opencga-storage-hadoop-deps-hdp3.1/pom.xml | 2 +- .../opencga-storage-hadoop-deps/pom.xml | 2 +- opencga-storage/opencga-storage-hadoop/pom.xml | 2 +- opencga-storage/opencga-storage-server/pom.xml | 2 +- opencga-storage/pom.xml | 2 +- opencga-test/pom.xml | 2 +- pom.xml | 14 +++++++------- 21 files changed, 27 insertions(+), 27 deletions(-) diff --git a/opencga-analysis/pom.xml b/opencga-analysis/pom.xml index 0e8c8b94814..01544f3538a 100644 --- a/opencga-analysis/pom.xml +++ b/opencga-analysis/pom.xml @@ -22,7 +22,7 @@ org.opencb.opencga opencga - 2.12.5-SNAPSHOT + 2.12.5 ../pom.xml diff --git a/opencga-app/pom.xml b/opencga-app/pom.xml index ae72959c680..afbb2c15342 100644 --- a/opencga-app/pom.xml +++ b/opencga-app/pom.xml @@ -22,7 +22,7 @@ org.opencb.opencga opencga - 2.12.5-SNAPSHOT + 2.12.5 ../pom.xml diff --git a/opencga-catalog/pom.xml b/opencga-catalog/pom.xml index 120850f20f8..f4971939bbb 100644 --- a/opencga-catalog/pom.xml +++ b/opencga-catalog/pom.xml @@ -23,7 +23,7 @@ org.opencb.opencga opencga - 2.12.5-SNAPSHOT + 2.12.5 ../pom.xml diff --git a/opencga-client/pom.xml b/opencga-client/pom.xml index dfe20bc1c6d..700c1de69c7 100644 --- a/opencga-client/pom.xml +++ b/opencga-client/pom.xml @@ -22,7 +22,7 @@ org.opencb.opencga opencga - 2.12.5-SNAPSHOT + 2.12.5 ../pom.xml diff --git a/opencga-clinical/pom.xml b/opencga-clinical/pom.xml index e17ae02a3c5..bdae22a335a 100644 --- a/opencga-clinical/pom.xml +++ b/opencga-clinical/pom.xml @@ -5,7 +5,7 @@ org.opencb.opencga opencga - 2.12.5-SNAPSHOT + 2.12.5 ../pom.xml 4.0.0 diff --git a/opencga-core/pom.xml b/opencga-core/pom.xml index f64f0c82cd5..dab473a7362 100644 --- a/opencga-core/pom.xml +++ b/opencga-core/pom.xml @@ -22,7 +22,7 @@ org.opencb.opencga opencga - 2.12.5-SNAPSHOT + 2.12.5 ../pom.xml diff --git a/opencga-master/pom.xml b/opencga-master/pom.xml index 3010de9e741..83d7becd861 100644 --- a/opencga-master/pom.xml +++ b/opencga-master/pom.xml @@ -22,7 +22,7 @@ opencga org.opencb.opencga - 2.12.5-SNAPSHOT + 2.12.5 ../pom.xml diff --git a/opencga-server/pom.xml b/opencga-server/pom.xml index 35730710dd5..e206eec5c95 100644 --- a/opencga-server/pom.xml +++ b/opencga-server/pom.xml @@ -22,7 +22,7 @@ org.opencb.opencga opencga - 2.12.5-SNAPSHOT + 2.12.5 ../pom.xml diff --git a/opencga-storage/opencga-storage-app/pom.xml b/opencga-storage/opencga-storage-app/pom.xml index dee5f5ab22d..47262e2c647 100644 --- a/opencga-storage/opencga-storage-app/pom.xml +++ b/opencga-storage/opencga-storage-app/pom.xml @@ -22,7 +22,7 @@ org.opencb.opencga opencga-storage - 2.12.5-SNAPSHOT + 2.12.5 ../pom.xml diff --git a/opencga-storage/opencga-storage-benchmark/pom.xml b/opencga-storage/opencga-storage-benchmark/pom.xml index f566fb8d61a..6ebbd4567c9 100644 --- a/opencga-storage/opencga-storage-benchmark/pom.xml +++ b/opencga-storage/opencga-storage-benchmark/pom.xml @@ -22,7 +22,7 @@ opencga-storage org.opencb.opencga - 2.12.5-SNAPSHOT + 2.12.5 ../pom.xml diff --git a/opencga-storage/opencga-storage-core/pom.xml b/opencga-storage/opencga-storage-core/pom.xml index d2569f51505..bb9e72406d9 100644 --- a/opencga-storage/opencga-storage-core/pom.xml +++ b/opencga-storage/opencga-storage-core/pom.xml @@ -22,7 +22,7 @@ org.opencb.opencga opencga-storage - 2.12.5-SNAPSHOT + 2.12.5 ../pom.xml diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/pom.xml b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/pom.xml index 98684f89345..44301eb5b63 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/pom.xml +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/pom.xml @@ -23,7 +23,7 @@ org.opencb.opencga opencga-storage-hadoop - 2.12.5-SNAPSHOT + 2.12.5 ../pom.xml diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-deps/opencga-storage-hadoop-deps-emr6.1/pom.xml b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-deps/opencga-storage-hadoop-deps-emr6.1/pom.xml index c40bd0c545e..85bd6a7da66 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-deps/opencga-storage-hadoop-deps-emr6.1/pom.xml +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-deps/opencga-storage-hadoop-deps-emr6.1/pom.xml @@ -22,7 +22,7 @@ org.opencb.opencga opencga-storage-hadoop-deps - 2.12.5-SNAPSHOT + 2.12.5 ../pom.xml diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-deps/opencga-storage-hadoop-deps-hdp2.6/pom.xml b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-deps/opencga-storage-hadoop-deps-hdp2.6/pom.xml index f2ab268c070..a15d1e80dbd 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-deps/opencga-storage-hadoop-deps-hdp2.6/pom.xml +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-deps/opencga-storage-hadoop-deps-hdp2.6/pom.xml @@ -22,7 +22,7 @@ org.opencb.opencga opencga-storage-hadoop-deps - 2.12.5-SNAPSHOT + 2.12.5 ../pom.xml diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-deps/opencga-storage-hadoop-deps-hdp3.1/pom.xml b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-deps/opencga-storage-hadoop-deps-hdp3.1/pom.xml index c78627c4980..5a107fec8fc 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-deps/opencga-storage-hadoop-deps-hdp3.1/pom.xml +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-deps/opencga-storage-hadoop-deps-hdp3.1/pom.xml @@ -22,7 +22,7 @@ org.opencb.opencga opencga-storage-hadoop-deps - 2.12.5-SNAPSHOT + 2.12.5 ../pom.xml diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-deps/pom.xml b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-deps/pom.xml index 5f0d66e4a26..0790a13a764 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-deps/pom.xml +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-deps/pom.xml @@ -50,7 +50,7 @@ org.opencb.opencga opencga-storage-hadoop - 2.12.5-SNAPSHOT + 2.12.5 ../pom.xml diff --git a/opencga-storage/opencga-storage-hadoop/pom.xml b/opencga-storage/opencga-storage-hadoop/pom.xml index ede0e9d5479..a4e177c4403 100644 --- a/opencga-storage/opencga-storage-hadoop/pom.xml +++ b/opencga-storage/opencga-storage-hadoop/pom.xml @@ -28,7 +28,7 @@ org.opencb.opencga opencga-storage - 2.12.5-SNAPSHOT + 2.12.5 ../pom.xml diff --git a/opencga-storage/opencga-storage-server/pom.xml b/opencga-storage/opencga-storage-server/pom.xml index 46032914536..9403f1ba8f9 100644 --- a/opencga-storage/opencga-storage-server/pom.xml +++ b/opencga-storage/opencga-storage-server/pom.xml @@ -22,7 +22,7 @@ org.opencb.opencga opencga-storage - 2.12.5-SNAPSHOT + 2.12.5 ../pom.xml diff --git a/opencga-storage/pom.xml b/opencga-storage/pom.xml index b318a6c26bb..3c31682fb6e 100644 --- a/opencga-storage/pom.xml +++ b/opencga-storage/pom.xml @@ -22,7 +22,7 @@ org.opencb.opencga opencga - 2.12.5-SNAPSHOT + 2.12.5 ../pom.xml diff --git a/opencga-test/pom.xml b/opencga-test/pom.xml index ae075a55888..a1df570546a 100644 --- a/opencga-test/pom.xml +++ b/opencga-test/pom.xml @@ -24,7 +24,7 @@ org.opencb.opencga opencga - 2.12.5-SNAPSHOT + 2.12.5 ../pom.xml diff --git a/pom.xml b/pom.xml index 29536c3be50..1bc6c3f8de1 100644 --- a/pom.xml +++ b/pom.xml @@ -22,7 +22,7 @@ org.opencb.opencga opencga - 2.12.5-SNAPSHOT + 2.12.5 pom OpenCGA @@ -43,12 +43,12 @@ - 2.12.5_dev - 2.12.5_dev - 5.8.4-SNAPSHOT - 2.12.3-SNAPSHOT - 4.12.1-SNAPSHOT - 2.12.5-SNAPSHOT + 2.12.5 + 2.12.5 + 5.8.3 + 2.12.2 + 4.12.0 + 2.12.5 0.2.0 2.11.4 From 4210acdda8c43cd34f243aecfd980dda134de541 Mon Sep 17 00:00:00 2001 From: JuanfeSanahuja Date: Thu, 6 Jun 2024 10:00:01 +0200 Subject: [PATCH 84/85] Prepare merge #TASK-6357 --- opencga-analysis/pom.xml | 2 +- opencga-app/pom.xml | 2 +- opencga-catalog/pom.xml | 2 +- opencga-client/pom.xml | 2 +- opencga-clinical/pom.xml | 2 +- opencga-core/pom.xml | 2 +- opencga-master/pom.xml | 2 +- opencga-server/pom.xml | 2 +- opencga-storage/opencga-storage-app/pom.xml | 2 +- opencga-storage/opencga-storage-benchmark/pom.xml | 2 +- opencga-storage/opencga-storage-core/pom.xml | 2 +- .../opencga-storage-hadoop/opencga-storage-hadoop-core/pom.xml | 2 +- .../opencga-storage-hadoop-deps-emr6.1/pom.xml | 2 +- .../opencga-storage-hadoop-deps-hdp2.6/pom.xml | 2 +- .../opencga-storage-hadoop-deps-hdp3.1/pom.xml | 2 +- .../opencga-storage-hadoop/opencga-storage-hadoop-deps/pom.xml | 2 +- opencga-storage/opencga-storage-hadoop/pom.xml | 2 +- opencga-storage/opencga-storage-server/pom.xml | 2 +- opencga-storage/pom.xml | 2 +- opencga-test/pom.xml | 2 +- pom.xml | 2 +- 21 files changed, 21 insertions(+), 21 deletions(-) diff --git a/opencga-analysis/pom.xml b/opencga-analysis/pom.xml index 01544f3538a..0f813f7c5db 100644 --- a/opencga-analysis/pom.xml +++ b/opencga-analysis/pom.xml @@ -22,7 +22,7 @@ org.opencb.opencga opencga - 2.12.5 + 3.2.0-SNAPSHOT ../pom.xml diff --git a/opencga-app/pom.xml b/opencga-app/pom.xml index afbb2c15342..1f9cf6c22f8 100644 --- a/opencga-app/pom.xml +++ b/opencga-app/pom.xml @@ -22,7 +22,7 @@ org.opencb.opencga opencga - 2.12.5 + 3.2.0-SNAPSHOT ../pom.xml diff --git a/opencga-catalog/pom.xml b/opencga-catalog/pom.xml index f4971939bbb..3da23d9c231 100644 --- a/opencga-catalog/pom.xml +++ b/opencga-catalog/pom.xml @@ -23,7 +23,7 @@ org.opencb.opencga opencga - 2.12.5 + 3.2.0-SNAPSHOT ../pom.xml diff --git a/opencga-client/pom.xml b/opencga-client/pom.xml index 700c1de69c7..2582a5f2003 100644 --- a/opencga-client/pom.xml +++ b/opencga-client/pom.xml @@ -22,7 +22,7 @@ org.opencb.opencga opencga - 2.12.5 + 3.2.0-SNAPSHOT ../pom.xml diff --git a/opencga-clinical/pom.xml b/opencga-clinical/pom.xml index bdae22a335a..16aff526b3e 100644 --- a/opencga-clinical/pom.xml +++ b/opencga-clinical/pom.xml @@ -5,7 +5,7 @@ org.opencb.opencga opencga - 2.12.5 + 3.2.0-SNAPSHOT ../pom.xml 4.0.0 diff --git a/opencga-core/pom.xml b/opencga-core/pom.xml index dab473a7362..73047a516e9 100644 --- a/opencga-core/pom.xml +++ b/opencga-core/pom.xml @@ -22,7 +22,7 @@ org.opencb.opencga opencga - 2.12.5 + 3.2.0-SNAPSHOT ../pom.xml diff --git a/opencga-master/pom.xml b/opencga-master/pom.xml index 83d7becd861..2348ef6f6f7 100644 --- a/opencga-master/pom.xml +++ b/opencga-master/pom.xml @@ -22,7 +22,7 @@ opencga org.opencb.opencga - 2.12.5 + 3.2.0-SNAPSHOT ../pom.xml diff --git a/opencga-server/pom.xml b/opencga-server/pom.xml index e206eec5c95..dc82a699d5c 100644 --- a/opencga-server/pom.xml +++ b/opencga-server/pom.xml @@ -22,7 +22,7 @@ org.opencb.opencga opencga - 2.12.5 + 3.2.0-SNAPSHOT ../pom.xml diff --git a/opencga-storage/opencga-storage-app/pom.xml b/opencga-storage/opencga-storage-app/pom.xml index 47262e2c647..c0f663c9273 100644 --- a/opencga-storage/opencga-storage-app/pom.xml +++ b/opencga-storage/opencga-storage-app/pom.xml @@ -22,7 +22,7 @@ org.opencb.opencga opencga-storage - 2.12.5 + 3.2.0-SNAPSHOT ../pom.xml diff --git a/opencga-storage/opencga-storage-benchmark/pom.xml b/opencga-storage/opencga-storage-benchmark/pom.xml index 6ebbd4567c9..4caf8dfd284 100644 --- a/opencga-storage/opencga-storage-benchmark/pom.xml +++ b/opencga-storage/opencga-storage-benchmark/pom.xml @@ -22,7 +22,7 @@ opencga-storage org.opencb.opencga - 2.12.5 + 3.2.0-SNAPSHOT ../pom.xml diff --git a/opencga-storage/opencga-storage-core/pom.xml b/opencga-storage/opencga-storage-core/pom.xml index bb9e72406d9..80ccc7fda39 100644 --- a/opencga-storage/opencga-storage-core/pom.xml +++ b/opencga-storage/opencga-storage-core/pom.xml @@ -22,7 +22,7 @@ org.opencb.opencga opencga-storage - 2.12.5 + 3.2.0-SNAPSHOT ../pom.xml diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/pom.xml b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/pom.xml index 44301eb5b63..f92db03f2a8 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/pom.xml +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-core/pom.xml @@ -23,7 +23,7 @@ org.opencb.opencga opencga-storage-hadoop - 2.12.5 + 3.2.0-SNAPSHOT ../pom.xml diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-deps/opencga-storage-hadoop-deps-emr6.1/pom.xml b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-deps/opencga-storage-hadoop-deps-emr6.1/pom.xml index 85bd6a7da66..f959da03bb9 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-deps/opencga-storage-hadoop-deps-emr6.1/pom.xml +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-deps/opencga-storage-hadoop-deps-emr6.1/pom.xml @@ -22,7 +22,7 @@ org.opencb.opencga opencga-storage-hadoop-deps - 2.12.5 + 3.2.0-SNAPSHOT ../pom.xml diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-deps/opencga-storage-hadoop-deps-hdp2.6/pom.xml b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-deps/opencga-storage-hadoop-deps-hdp2.6/pom.xml index a15d1e80dbd..d360a3a982c 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-deps/opencga-storage-hadoop-deps-hdp2.6/pom.xml +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-deps/opencga-storage-hadoop-deps-hdp2.6/pom.xml @@ -22,7 +22,7 @@ org.opencb.opencga opencga-storage-hadoop-deps - 2.12.5 + 3.2.0-SNAPSHOT ../pom.xml diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-deps/opencga-storage-hadoop-deps-hdp3.1/pom.xml b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-deps/opencga-storage-hadoop-deps-hdp3.1/pom.xml index 5a107fec8fc..5b48f8741a5 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-deps/opencga-storage-hadoop-deps-hdp3.1/pom.xml +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-deps/opencga-storage-hadoop-deps-hdp3.1/pom.xml @@ -22,7 +22,7 @@ org.opencb.opencga opencga-storage-hadoop-deps - 2.12.5 + 3.2.0-SNAPSHOT ../pom.xml diff --git a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-deps/pom.xml b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-deps/pom.xml index 0790a13a764..e85ee78fe4e 100644 --- a/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-deps/pom.xml +++ b/opencga-storage/opencga-storage-hadoop/opencga-storage-hadoop-deps/pom.xml @@ -50,7 +50,7 @@ org.opencb.opencga opencga-storage-hadoop - 2.12.5 + 3.2.0-SNAPSHOT ../pom.xml diff --git a/opencga-storage/opencga-storage-hadoop/pom.xml b/opencga-storage/opencga-storage-hadoop/pom.xml index a4e177c4403..4e0ebd27ca0 100644 --- a/opencga-storage/opencga-storage-hadoop/pom.xml +++ b/opencga-storage/opencga-storage-hadoop/pom.xml @@ -28,7 +28,7 @@ org.opencb.opencga opencga-storage - 2.12.5 + 3.2.0-SNAPSHOT ../pom.xml diff --git a/opencga-storage/opencga-storage-server/pom.xml b/opencga-storage/opencga-storage-server/pom.xml index 9403f1ba8f9..d6d92f43dda 100644 --- a/opencga-storage/opencga-storage-server/pom.xml +++ b/opencga-storage/opencga-storage-server/pom.xml @@ -22,7 +22,7 @@ org.opencb.opencga opencga-storage - 2.12.5 + 3.2.0-SNAPSHOT ../pom.xml diff --git a/opencga-storage/pom.xml b/opencga-storage/pom.xml index 3c31682fb6e..2cbf9a9aa24 100644 --- a/opencga-storage/pom.xml +++ b/opencga-storage/pom.xml @@ -22,7 +22,7 @@ org.opencb.opencga opencga - 2.12.5 + 3.2.0-SNAPSHOT ../pom.xml diff --git a/opencga-test/pom.xml b/opencga-test/pom.xml index a1df570546a..89275c6e710 100644 --- a/opencga-test/pom.xml +++ b/opencga-test/pom.xml @@ -24,7 +24,7 @@ org.opencb.opencga opencga - 2.12.5 + 3.2.0-SNAPSHOT ../pom.xml diff --git a/pom.xml b/pom.xml index 1bc6c3f8de1..92a8489aba6 100644 --- a/pom.xml +++ b/pom.xml @@ -22,7 +22,7 @@ org.opencb.opencga opencga - 2.12.5 + 3.2.0-SNAPSHOT pom OpenCGA From 60279a1c403b3dc729d600419d59e686946ae62c Mon Sep 17 00:00:00 2001 From: pfurio Date: Fri, 7 Jun 2024 15:11:43 +0200 Subject: [PATCH 85/85] catalog: fix catalog tests failing, #TASK-6357 --- .../opencb/opencga/catalog/managers/CatalogManagerTest.java | 2 +- .../opencb/opencga/catalog/managers/FileManagerTest.java | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/opencga-catalog/src/test/java/org/opencb/opencga/catalog/managers/CatalogManagerTest.java b/opencga-catalog/src/test/java/org/opencb/opencga/catalog/managers/CatalogManagerTest.java index 3330f463938..6f23a58d78d 100644 --- a/opencga-catalog/src/test/java/org/opencb/opencga/catalog/managers/CatalogManagerTest.java +++ b/opencga-catalog/src/test/java/org/opencb/opencga/catalog/managers/CatalogManagerTest.java @@ -429,7 +429,7 @@ private String getAdminToken() throws CatalogException, IOException { @Test public void createUserUsingMailAsId() throws CatalogException { - catalogManager.getUserManager().create(new User().setId("hello.mail@mymail.org").setName("Hello"), TestParamConstants.PASSWORD, opencgaToken); + catalogManager.getUserManager().create(new User().setId("hello.mail@mymail.org").setName("Hello"), TestParamConstants.PASSWORD, ownerToken); AuthenticationResponse login = catalogManager.getUserManager().login(organizationId, "hello.mail@mymail.org", TestParamConstants.PASSWORD); assertNotNull(login); User user = catalogManager.getUserManager().get(organizationId, "hello.mail@mymail.org", new QueryOptions(), login.getToken()).first(); diff --git a/opencga-catalog/src/test/java/org/opencb/opencga/catalog/managers/FileManagerTest.java b/opencga-catalog/src/test/java/org/opencb/opencga/catalog/managers/FileManagerTest.java index 1fad053fb77..5e655998abd 100644 --- a/opencga-catalog/src/test/java/org/opencb/opencga/catalog/managers/FileManagerTest.java +++ b/opencga-catalog/src/test/java/org/opencb/opencga/catalog/managers/FileManagerTest.java @@ -199,7 +199,7 @@ public void testLinkFileWithoutReadPermissions() throws IOException, CatalogExce public void filterByFormatTest() throws CatalogException { Query query = new Query(FileDBAdaptor.QueryParams.FORMAT.key(), "PLAIN"); OpenCGAResult search = catalogManager.getFileManager().search(studyFqn, query, QueryOptions.empty(), ownerToken); - assertEquals(2, search.getNumResults()); + assertEquals(3, search.getNumResults()); query = new Query(FileDBAdaptor.QueryParams.FORMAT.key(), "plain"); search = catalogManager.getFileManager().search(studyFqn, query, QueryOptions.empty(), ownerToken); @@ -213,12 +213,12 @@ public void filterByFormatTest() throws CatalogException { // Case sensitive in upper case query = new Query(FileDBAdaptor.QueryParams.FORMAT.key(), "~/^PLA/"); search = catalogManager.getFileManager().search(studyFqn, query, QueryOptions.empty(), ownerToken); - assertEquals(2, search.getNumResults()); + assertEquals(3, search.getNumResults()); // Case insensitive search query = new Query(FileDBAdaptor.QueryParams.FORMAT.key(), "~/^pla/i"); search = catalogManager.getFileManager().search(studyFqn, query, QueryOptions.empty(), ownerToken); - assertEquals(2, search.getNumResults()); + assertEquals(3, search.getNumResults()); } @Test