From 63baa43aef065ac002e270e9f529989ec90cd160 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joaqu=C3=ADn=20T=C3=A1rraga=20Gim=C3=A9nez?= Date: Fri, 20 Sep 2024 12:59:28 +0200 Subject: [PATCH] analysis: improve family QC and add JUnit test, #TASK-6772, #TASK-6766 --- .../family/qc/FamilyVariantQcAnalysis.java | 32 +++++++++++------- .../variant/qc/VariantQcAnalysis.java | 26 +++++++++++--- .../variant/OpenCGATestExternalResource.java | 15 ++++++++ .../analysis/variant/VariantAnalysisTest.java | 29 ++++++++++++---- .../test/resources/variant-test-file.vcf.gz | Bin 21524 -> 21632 bytes 5 files changed, 80 insertions(+), 22 deletions(-) diff --git a/opencga-analysis/src/main/java/org/opencb/opencga/analysis/family/qc/FamilyVariantQcAnalysis.java b/opencga-analysis/src/main/java/org/opencb/opencga/analysis/family/qc/FamilyVariantQcAnalysis.java index 81a2346e14d..6e4d0a0ab17 100644 --- a/opencga-analysis/src/main/java/org/opencb/opencga/analysis/family/qc/FamilyVariantQcAnalysis.java +++ b/opencga-analysis/src/main/java/org/opencb/opencga/analysis/family/qc/FamilyVariantQcAnalysis.java @@ -26,6 +26,7 @@ import org.apache.commons.lang3.StringUtils; import org.opencb.biodata.models.clinical.qc.Relatedness; import org.opencb.biodata.models.variant.avro.VariantType; +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.qc.VariantQcAnalysis; @@ -74,19 +75,21 @@ public class FamilyVariantQcAnalysis extends VariantQcAnalysis { @Override protected void check() throws Exception { + // IMPORTANT: the first thing to do since it initializes "study" from params.get(STUDY_PARAM) + super.check(); + setUpStorageEngineExecutor(study); // Check parameters - super.check(); - checkParameters(analysisParams, getStudy(), catalogManager, token); + checkParameters(analysisParams, study, catalogManager, token); // Check custom resources path - userResourcesPath = checkResourcesDir(analysisParams.getResourcesDir(), getStudy(), catalogManager, token); + userResourcesPath = checkResourcesDir(analysisParams.getResourcesDir(), study, catalogManager, token); } @Override protected List getSteps() { - List steps = Arrays.asList(PREPARE_QC_STEP, ID); + List steps = new ArrayList<>(Arrays.asList(PREPARE_QC_STEP, ID)); if (!Boolean.TRUE.equals(analysisParams.getSkipIndex())) { steps.add(INDEX_QC_STEP); } @@ -131,7 +134,7 @@ protected void prepareQualityControl() throws ToolException { // Create query options QueryOptions queryOptions = new QueryOptions().append(QueryOptions.INCLUDE, "id,studies.samples"); - // Export to VCF.GZ format + // Export variants (VCF.GZ format) String basename = getOutDir().resolve(familyId).toAbsolutePath().toString(); getVariantStorageManager().exportData(basename, VCF_GZ, null, query, queryOptions, token); @@ -144,11 +147,11 @@ protected void prepareQualityControl() throws ToolException { } vcfPaths.add(vcfPath); - // Export family (JSON format) - Path jsonPath = Paths.get(basename + "." + JSON.getExtension()); + // Write family (JSON format) + Path jsonPath = Paths.get(basename + "_info." + JSON.getExtension()); objectWriter.writeValue(jsonPath.toFile(), family); - // Check VCF file + // Check JSON file if (!Files.exists(jsonPath)) { throw new ToolException("Something wrong happened when saving JSON file for family ID " + familyId + ". JSON file " + jsonPath + " was not created."); @@ -189,7 +192,8 @@ protected void indexQualityControl() throws ToolException { familyQc = new FamilyQualityControl(); // Check and parse the relatedness output file - Path qcPath = getOutDir().resolve(family.getId()).resolve(RELATEDNESS_ANALYSIS_ID + QC_JSON_EXTENSION); + Path qcPath = getOutDir().resolve(family.getId()).resolve(RELATEDNESS_ANALYSIS_ID) + .resolve(RELATEDNESS_ANALYSIS_ID + QC_JSON_EXTENSION); if (!Files.exists(qcPath)) { failedQcSet.add(family.getId()); qcStatus = new QualityControlStatus(ERROR, FAILURE_FILE + qcPath.getFileName() + NOT_FOUND); @@ -199,11 +203,16 @@ protected void indexQualityControl() throws ToolException { logger.error(logMsg); } else { try { - List relatedness = isQcArray(qcPath) + List relatednessList = isQcArray(qcPath) ? relatednessListReader.readValue(qcPath.toFile()) : Collections.singletonList(relatednessReader.readValue(qcPath.toFile())); - familyQc.setRelatedness(relatedness); + // Set common attributes + for (Relatedness relatedness : relatednessList) { + addCommonAttributes(relatedness.getAttributes()); + } + + familyQc.setRelatedness(relatednessList); qcStatus = new QualityControlStatus(READY, SUCCESS); } catch (IOException e) { failedQcSet.add(family.getId()); @@ -233,7 +242,6 @@ protected void indexQualityControl() throws ToolException { checkFailedQcCounter(families.size(), FAMILY_QC_TYPE); } - public static void checkParameters(FamilyQcAnalysisParams params, String studyId, CatalogManager catalogManager, String token) throws ToolException { // Check study diff --git a/opencga-analysis/src/main/java/org/opencb/opencga/analysis/variant/qc/VariantQcAnalysis.java b/opencga-analysis/src/main/java/org/opencb/opencga/analysis/variant/qc/VariantQcAnalysis.java index 7c4cef38804..7fca635b622 100644 --- a/opencga-analysis/src/main/java/org/opencb/opencga/analysis/variant/qc/VariantQcAnalysis.java +++ b/opencga-analysis/src/main/java/org/opencb/opencga/analysis/variant/qc/VariantQcAnalysis.java @@ -22,6 +22,7 @@ import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.io.FileUtils; import org.apache.commons.lang3.StringUtils; +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.ResourceUtils; @@ -100,6 +101,9 @@ public class VariantQcAnalysis extends OpenCgaToolScopeStudy { + " in OpenCGA catalog"; protected static final String SUCCESS = "Success"; + // Common attributes + public static final String OPENCGA_JOB_ID_ATTR = "OPENCGA_JOB_ID"; + protected LinkedList vcfPaths = new LinkedList<>(); protected LinkedList jsonPaths = new LinkedList<>(); @@ -247,6 +251,19 @@ protected boolean isQcArray(Path qcPath) throws ToolException { } } + protected void addCommonAttributes(ObjectMap attributes) { + if (attributes != null) { + attributes.append(OPENCGA_JOB_ID_ATTR, getJobId()); + } else { + String msg = "Could not add common attributes, such as " + OPENCGA_JOB_ID_ATTR; + try { + addWarning(msg); + } catch (ToolException e) { + logger.warn(msg, e); + } + } + } + protected T parseQcFile(String id, String analysisId, List skip, Path qcPath, String qcType, ObjectReader reader) throws ToolException { if (CollectionUtils.isEmpty(skip) || !skip.contains(analysisId)) { @@ -356,15 +373,16 @@ protected void downloadQcResourceFile(String resourceName, Path destPath) throws protected void copyUserResourceFiles() throws ToolException { // Sanity check - if (userResourcesPath == null) { - // Nothing to do - return; + if (userResourcesPath != null && Files.exists(userResourcesPath)) { + copyUserResourceFiles(userResourcesPath); } + } + protected void copyUserResourceFiles(Path inputPath) throws ToolException { Path destResourcesPath = checkResourcesPath(getOutDir().resolve(RESOURCES_FOLDER)); // Copy custom resource files to the job dir - for (java.io.File file : userResourcesPath.toFile().listFiles()) { + for (java.io.File file : inputPath.toFile().listFiles()) { Path destPath = destResourcesPath.resolve(file.getName()); if (file.isFile()) { try { diff --git a/opencga-analysis/src/test/java/org/opencb/opencga/analysis/variant/OpenCGATestExternalResource.java b/opencga-analysis/src/test/java/org/opencb/opencga/analysis/variant/OpenCGATestExternalResource.java index 5c5956d7cf7..20cb16343fd 100644 --- a/opencga-analysis/src/test/java/org/opencb/opencga/analysis/variant/OpenCGATestExternalResource.java +++ b/opencga-analysis/src/test/java/org/opencb/opencga/analysis/variant/OpenCGATestExternalResource.java @@ -268,6 +268,21 @@ public Path isolateOpenCGA() throws IOException { Files.copy(inputStream, analysisPath.resolve(exomiserFile), StandardCopyOption.REPLACE_EXISTING); } + // QC + analysisPath = Files.createDirectories(opencgaHome.resolve("analysis/qc")).toAbsolutePath(); + List qcFiles = Arrays.asList("variant_qc.main.py", "utils.py", "__init__.py"); + for (String qcFile : qcFiles) { + inputStream = new FileInputStream("../opencga-app/app/analysis/qc/" + qcFile); + Files.copy(inputStream, analysisPath.resolve(qcFile), StandardCopyOption.REPLACE_EXISTING); + } + // Family QC + analysisPath = Files.createDirectories(opencgaHome.resolve("analysis/qc/family_qc")).toAbsolutePath(); + qcFiles = Arrays.asList("family_qc.py", "__init__.py"); + for (String qcFile : qcFiles) { + inputStream = new FileInputStream("../opencga-app/app/analysis/qc/family_qc/" + qcFile); + Files.copy(inputStream, analysisPath.resolve(qcFile), StandardCopyOption.REPLACE_EXISTING); + } + return opencgaHome; } 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 2d3d703896b..b0ed47095f2 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 @@ -62,6 +62,7 @@ import org.opencb.opencga.core.api.ParamConstants; import org.opencb.opencga.core.common.ExceptionUtils; import org.opencb.opencga.core.common.JacksonUtils; +import org.opencb.opencga.core.common.TimeUtils; import org.opencb.opencga.core.config.storage.CellBaseConfiguration; import org.opencb.opencga.core.config.storage.StorageConfiguration; import org.opencb.opencga.core.exceptions.ToolException; @@ -116,8 +117,7 @@ import static org.hamcrest.CoreMatchers.hasItem; import static org.junit.Assert.*; -import static org.opencb.opencga.analysis.variant.qc.VariantQcAnalysis.GENOME_PLOT_ANALYSIS_ID; -import static org.opencb.opencga.analysis.variant.qc.VariantQcAnalysis.SIGNATURE_ANALYSIS_ID; +import static org.opencb.opencga.analysis.variant.qc.VariantQcAnalysis.*; import static org.opencb.opencga.storage.core.variant.VariantStorageBaseTest.getResourceUri; @RunWith(Parameterized.class) @@ -1111,22 +1111,39 @@ public void testPedigreeGraph() throws CatalogException { public void testFamilyQC() throws Exception { Path outDir = Paths.get(opencga.createTmpOutdir("_family_qc")); + // To be sure, all samples are no-somatic + SampleUpdateParams sampleUpdateParams = new SampleUpdateParams().setSomatic(false); + catalogManager.getSampleManager().update(STUDY, son, sampleUpdateParams, null, token); + // Update quality control for the cancer sample FamilyQualityControl qc = new FamilyQualityControl(); - FamilyUpdateParams updateParams = new FamilyUpdateParams().setQualityControl(qc); - catalogManager.getFamilyManager().update(STUDY, family, updateParams, null, token); + FamilyUpdateParams familyUpdateParams = new FamilyUpdateParams().setQualityControl(qc); + catalogManager.getFamilyManager().update(STUDY, family, familyUpdateParams, null, token); // Family QC analysis FamilyQcAnalysisParams params = new FamilyQcAnalysisParams(); params.setFamilies(Arrays.asList(family)); + String jobId = "test-family-qc-" + TimeUtils.getTimeMillis(); toolRunner.execute(FamilyVariantQcAnalysis.class, params, new ObjectMap(ParamConstants.STUDY_PARAM, STUDY), - outDir, null, false, token); + outDir, jobId, false, token); Family fam = catalogManager.getFamilyManager().get(STUDY, family, QueryOptions.empty(), token).first(); - System.out.println("fam.getInternal().getQualityControlStatus() = " + fam.getInternal().getQualityControlStatus()); + // Some output to check + System.out.println("fam.getInternal().getQualityControlStatus() = " + fam.getInternal().getQualityControlStatus()); + System.out.println("fam.getQualityControl() = " + fam.getQualityControl()); System.out.println("outDir = " + outDir); + + // Restore + sampleUpdateParams = new SampleUpdateParams().setSomatic(true); + catalogManager.getSampleManager().update(STUDY, son, sampleUpdateParams, null, token); + + // Asserts + assertEquals(fam.getInternal().getQualityControlStatus().getId(), QualityControlStatus.READY); + assertNotNull(fam.getQualityControl()); + assertEquals(1, fam.getQualityControl().getRelatedness().size()); + assertEquals(jobId, fam.getQualityControl().getRelatedness().get(0).getAttributes().get(OPENCGA_JOB_ID_ATTR)); } @Test diff --git a/opencga-storage/opencga-storage-core/src/test/resources/variant-test-file.vcf.gz b/opencga-storage/opencga-storage-core/src/test/resources/variant-test-file.vcf.gz index d055502aaea6aa5d4b3a9173135c7fd071ebc734..a36566122cb34521427a9e2a4eae48c8dec2c2c3 100644 GIT binary patch delta 13021 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 delta 12894 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 If~IH!08`=6fB*mh