Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,11 @@
package org.opencb.opencga.analysis.family.qc;

import org.apache.commons.lang3.StringUtils;
import org.opencb.biodata.models.clinical.qc.RelatednessReport;
import org.opencb.commons.datastore.core.QueryOptions;
import org.opencb.opencga.analysis.AnalysisUtils;
import org.opencb.opencga.analysis.individual.qc.IndividualQcUtils;
import org.opencb.opencga.analysis.tools.OpenCgaTool;
import org.opencb.opencga.analysis.tools.OpenCgaToolScopeStudy;
import org.opencb.opencga.analysis.variant.relatedness.RelatednessAnalysis;
import org.opencb.opencga.catalog.exceptions.CatalogException;
import org.opencb.opencga.catalog.utils.CatalogFqn;
Expand All @@ -32,7 +33,10 @@
import org.opencb.opencga.core.models.family.FamilyQualityControl;
import org.opencb.opencga.core.models.family.FamilyUpdateParams;
import org.opencb.opencga.core.models.study.Study;
import org.opencb.opencga.core.models.variant.FamilyQcAnalysisParams;
import org.opencb.opencga.core.models.variant.MutationalSignatureAnalysisParams;
import org.opencb.opencga.core.tools.annotations.Tool;
import org.opencb.opencga.core.tools.annotations.ToolParams;
import org.opencb.opencga.core.tools.variant.FamilyQcAnalysisExecutor;

import java.nio.file.Path;
Expand All @@ -43,62 +47,78 @@
import static org.opencb.opencga.core.models.study.StudyPermissions.Permissions.WRITE_FAMILIES;

@Tool(id = FamilyQcAnalysis.ID, resource = Enums.Resource.FAMILY, description = FamilyQcAnalysis.DESCRIPTION)
public class FamilyQcAnalysis extends OpenCgaTool {
public class FamilyQcAnalysis extends OpenCgaToolScopeStudy {

public static final String ID = "family-qc";
public static final String DESCRIPTION = "Run quality control (QC) for a given family. It computes the relatedness scores among the"
+ " family members";
+ " family members";

public static final String RELATEDNESS_STEP = "relatedness";

private String studyId;
private String familyId;
private String relatednessMethod;
@ToolParams
private FamilyQcAnalysisParams familyQcParams = new FamilyQcAnalysisParams();

private String relatednessMaf;
private String haploidCallMode;
private Map<String, Map<String, Float>> relatednessThresholds;

private Family family;

@Override
protected void check() throws Exception {
super.check();
setUpStorageEngineExecutor(studyId);
setUpStorageEngineExecutor(study);

if (StringUtils.isEmpty(studyId)) {
if (StringUtils.isEmpty(study)) {
throw new ToolException("Missing study ID.");
}

// Check permissions
try {
JwtPayload jwtPayload = catalogManager.getUserManager().validateToken(token);
CatalogFqn studyFqn = CatalogFqn.extractFqnFromStudy(studyId, jwtPayload);
CatalogFqn studyFqn = CatalogFqn.extractFqnFromStudy(study, jwtPayload);
String organizationId = studyFqn.getOrganizationId();
String userId = jwtPayload.getUserId(organizationId);

Study study = catalogManager.getStudyManager().get(studyId, QueryOptions.empty(), token).first();
catalogManager.getAuthorizationManager().checkStudyPermission(organizationId, study.getUid(), userId, WRITE_FAMILIES);
Study auxStudy = catalogManager.getStudyManager().get(study, QueryOptions.empty(), token).first();
catalogManager.getAuthorizationManager().checkStudyPermission(organizationId, auxStudy.getUid(), userId, WRITE_FAMILIES);
} catch (CatalogException e) {
throw new ToolException(e);
}

// Sanity check
if (StringUtils.isEmpty(familyId)) {
if (StringUtils.isEmpty(familyQcParams.getFamily())) {
throw new ToolException("Missing family ID.");
}

family = IndividualQcUtils.getFamilyById(studyId, familyId, catalogManager, token);
family = IndividualQcUtils.getFamilyById(study, familyQcParams.getFamily(), catalogManager, token);
if (family == null) {
throw new ToolException("Family '" + familyId + "' not found.");
throw new ToolException("Family '" + familyQcParams.getFamily() + "' not found.");
}

// As relatedness is the only QC to compute, it is mandatory
if (StringUtils.isEmpty(relatednessMethod)) {
relatednessMethod = "PLINK/IBD";
}
// Check MAF
relatednessMaf = familyQcParams.getRelatednessMaf();
if (StringUtils.isEmpty(relatednessMaf)) {
relatednessMaf = RelatednessAnalysis.MAF_DEFAULT_VALUE;
}

// Check haploid call mode
haploidCallMode = familyQcParams.getHaploidCallMode();
if (StringUtils.isEmpty(haploidCallMode)) {
haploidCallMode = RelatednessReport.HAPLOID_CALL_MODE_DEFAUT_VALUE;
} else {
switch (haploidCallMode) {
case RelatednessReport.HAPLOID_CALL_MODE_HAPLOID_VALUE:
case RelatednessReport.HAPLOID_CALL_MODE_MISSING_VALUE:
case RelatednessReport.HAPLOID_CALL_MODE_REF_VALUE:
break;
default:
throw new ToolException("Invalid haploid call value '" + haploidCallMode + "', accepted values are: "
+ RelatednessReport.HAPLOID_CALL_MODE_HAPLOID_VALUE + ", " + RelatednessReport.HAPLOID_CALL_MODE_MISSING_VALUE
+ " and " + RelatednessReport.HAPLOID_CALL_MODE_REF_VALUE);
}
}

Path thresholdsPath = getOpencgaHome().resolve("analysis").resolve(FamilyQcAnalysis.ID).resolve("relatedness_thresholds.csv");
relatednessThresholds = AnalysisUtils.parseRelatednessThresholds(thresholdsPath);
}
Expand All @@ -120,10 +140,10 @@ protected void run() throws ToolException {
FamilyQcAnalysisExecutor executor = getToolExecutor(FamilyQcAnalysisExecutor.class);

// Set up executor
executor.setStudyId(studyId)
executor.setStudyId(study)
.setFamily(family)
.setRelatednessMethod(relatednessMethod)
.setRelatednessMaf(relatednessMaf)
.setHaploidCallMode(haploidCallMode)
.setRelatednessThresholds(relatednessThresholds)
.setRelatednesResourcePath(getOpencgaHome().resolve("analysis/resources").resolve(RelatednessAnalysis.ID))
.setQualityControl(qualityControl);
Expand All @@ -135,47 +155,29 @@ protected void run() throws ToolException {
try {
qualityControl = executor.getQualityControl();
if (qualityControl != null) {
catalogManager.getFamilyManager().update(getStudyId(), familyId, new FamilyUpdateParams().setQualityControl(qualityControl),
catalogManager.getFamilyManager().update(study, familyQcParams.getFamily(), new FamilyUpdateParams().setQualityControl(qualityControl),
QueryOptions.empty(), token);
}
} catch (CatalogException e) {
throw new ToolException(e);
}
}

public String getStudyId() {
return studyId;
}

public FamilyQcAnalysis setStudyId(String studyId) {
this.studyId = studyId;
return this;
}

public String getFamilyId() {
return familyId;
}

public FamilyQcAnalysis setFamilyId(String familyId) {
this.familyId = familyId;
return this;
}

public String getRelatednessMethod() {
return relatednessMethod;
public String getRelatednessMaf() {
return relatednessMaf;
}

public FamilyQcAnalysis setRelatednessMethod(String relatednessMethod) {
this.relatednessMethod = relatednessMethod;
public FamilyQcAnalysis setRelatednessMaf(String relatednessMaf) {
this.relatednessMaf = relatednessMaf;
return this;
}

public String getRelatednessMaf() {
return relatednessMaf;
public String getHaploidCallMode() {
return haploidCallMode;
}

public FamilyQcAnalysis setRelatednessMaf(String relatednessMaf) {
this.relatednessMaf = relatednessMaf;
public FamilyQcAnalysis setHaploidCallMode(String haploidCallMode) {
this.haploidCallMode = haploidCallMode;
return this;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,10 @@ private void runRelatedness() throws ToolException {

if (CollectionUtils.isNotEmpty(qualityControl.getRelatedness())) {
for (RelatednessReport relatedness : qualityControl.getRelatedness()) {
if (relatednessMethod.equals(relatedness.getMethod()) && relatednessMaf.equals(relatedness.getMaf())) {
if (IBDComputation.PLINK_IBD_METHOD.equals(relatedness.getMethod()) && relatednessMaf.equals(relatedness.getMaf())) {
// Nothing to update
addWarning("Skipping relatedness analysis: it was already computed for method '" + relatednessMethod + "' and MAF '"
+ relatednessMaf + "'");
addWarning("Skipping relatedness analysis: it was already computed for method '" + IBDComputation.PLINK_IBD_METHOD
+ "' and MAF '" + relatednessMaf + "'");
qualityControl = null;
return;
}
Expand Down Expand Up @@ -113,7 +113,7 @@ private void runRelatedness() throws ToolException {

// Run IBD/IBS computation using PLINK in docker
RelatednessReport report = IBDComputation.compute(getStudyId(), getFamily(), sampleIds, getRelatednessMaf(),
getRelatednessThresholds(), getRelatednesResourcePath(), getOutDir(), getVariantStorageManager(), getToken());
getHaploidCallMode(), getRelatednessThresholds(), getRelatednesResourcePath(), getOutDir(), getVariantStorageManager(), getToken());

// Sanity check
if (report == null) {
Expand Down
Loading