/*
* Copyright 2015-2016 OpenCB
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.opencb.opencga.server.rest.analysis;
import io.swagger.annotations.*;
import org.apache.commons.lang3.StringUtils;
import org.ga4gh.models.ReadAlignment;
import org.opencb.biodata.models.alignment.RegionCoverage;
import org.opencb.biodata.tools.alignment.stats.AlignmentGlobalStats;
import org.opencb.commons.datastore.core.Query;
import org.opencb.commons.datastore.core.QueryOptions;
import org.opencb.commons.datastore.core.QueryResponse;
import org.opencb.commons.datastore.core.QueryResult;
import org.opencb.opencga.core.exception.VersionException;
import org.opencb.opencga.storage.core.alignment.AlignmentDBAdaptor;
import org.opencb.opencga.storage.core.manager.AlignmentStorageManager;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.*;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;
import java.io.IOException;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
/**
* Created by imedina on 17/08/16.
*/
@Path("/{version}/analysis/alignment")
@Produces(MediaType.APPLICATION_JSON)
@Api(value = "Analysis - Alignment", position = 4, description = "Methods for working with 'files' endpoint")
public class AlignmentAnalysisWSService extends AnalysisWSService {
public AlignmentAnalysisWSService(@Context UriInfo uriInfo, @Context HttpServletRequest httpServletRequest)
throws IOException, VersionException {
super(uriInfo, httpServletRequest);
}
public AlignmentAnalysisWSService(String version, @Context UriInfo uriInfo, @Context HttpServletRequest httpServletRequest)
throws IOException, VersionException {
super(version, uriInfo, httpServletRequest);
}
@GET
@Path("/index")
@ApiOperation(value = "Index alignment files", position = 14, response = QueryResponse.class)
public Response index(@ApiParam(value = "Comma separated list of file ids (files or directories)", required = true)
@QueryParam(value = "file") String fileIdStr,
@ApiParam(value = "(DEPRECATED) Study id", hidden = true) @QueryParam("studyId") String studyId,
@ApiParam(value = "Study [[user@]project:]study where study and project can be either the id or alias")
@QueryParam("study") String studyStr,
@ApiParam("Boolean indicating that only the transform step will be run") @DefaultValue("false") @QueryParam("transform") boolean transform,
@ApiParam("Boolean indicating that only the load step will be run") @DefaultValue("false") @QueryParam("load") boolean load) {
if (StringUtils.isNotEmpty(studyId)) {
studyStr = studyId;
}
Map<String, String> params = new LinkedHashMap<>();
// addParamIfNotNull(params, "studyId", studyId);
addParamIfTrue(params, "transform", transform);
addParamIfTrue(params, "load", load);
logger.info("ObjectMap: {}", params);
try {
QueryResult queryResult = catalogManager.getFileManager().index(fileIdStr, studyStr, "BAM", params, sessionId);
return createOkResponse(queryResult);
} catch(Exception e) {
return createErrorResponse(e);
}
}
@GET
@Path("/query")
@ApiOperation(value = "Fetch alignments from a BAM file", position = 15, response = ReadAlignment[].class)
@ApiImplicitParams({
@ApiImplicitParam(name = "include", value = "Fields included in the response, whole JSON path must be provided",
example = "name,attributes", dataType = "string", paramType = "query"),
@ApiImplicitParam(name = "exclude", value = "Fields excluded in the response, whole JSON path must be provided",
example = "id,status", dataType = "string", paramType = "query"),
@ApiImplicitParam(name = "limit", value = "Number of results to be returned in the queries", dataType = "integer",
paramType = "query"),
@ApiImplicitParam(name = "skip", value = "Number of results to skip in the queries", dataType = "integer", paramType = "query"),
@ApiImplicitParam(name = "count", value = "Total number of results", dataType = "boolean", paramType = "query")
})
public Response getAlignments(@ApiParam(value = "Id of the alignment file in catalog", required = true) @QueryParam("file")
String fileIdStr,
@ApiParam(value = "(DEPRECATED) Study id", hidden = true) @QueryParam("studyId") String studyId,
@ApiParam(value = "Study [[user@]project:]study where study and project can be either the id or alias")
@QueryParam("study") String studyStr,
@ApiParam(value = "Comma separated list of regions 'chr:start-end'", required = false) @QueryParam
("region") String region,
@ApiParam(value = "Minimum mapping quality", required = false) @QueryParam("minMapQ") Integer minMapQ,
@ApiParam(value = "Only alignments completely contained within boundaries of region", required = false)
@QueryParam("contained") Boolean contained,
@ApiParam(value = "Force SAM MD optional field to be set with the alignments", required = false)
@QueryParam("mdField") Boolean mdField,
@ApiParam(value = "Compress the nucleotide qualities by using 8 quality levels", required = false)
@QueryParam("binQualities") Boolean binQualities) {
try {
if (StringUtils.isNotEmpty(studyId)) {
studyStr = studyId;
}
Query query = new Query();
query.putIfNotNull(AlignmentDBAdaptor.QueryParams.MIN_MAPQ.key(), minMapQ);
QueryOptions queryOptions = new QueryOptions();
queryOptions.putIfNotNull(AlignmentDBAdaptor.QueryParams.LIMIT.key(), limit);
queryOptions.putIfNotNull(AlignmentDBAdaptor.QueryParams.SKIP.key(), skip);
queryOptions.putIfNotNull("count", count);
queryOptions.putIfNotNull(AlignmentDBAdaptor.QueryParams.CONTAINED.key(), contained);
queryOptions.putIfNotNull(AlignmentDBAdaptor.QueryParams.MD_FIELD.key(), mdField);
queryOptions.putIfNotNull(AlignmentDBAdaptor.QueryParams.BIN_QUALITIES.key(), binQualities);
AlignmentStorageManager alignmentStorageManager = new AlignmentStorageManager(catalogManager, storageEngineFactory);
if (StringUtils.isNotEmpty(region)) {
String[] regionList = region.split(",");
List<QueryResult<ReadAlignment>> queryResultList = new ArrayList<>(regionList.length);
for (String regionAux : regionList) {
query.putIfNotNull(AlignmentDBAdaptor.QueryParams.REGION.key(), regionAux);
queryResultList.add(alignmentStorageManager.query(studyStr, fileIdStr, query, queryOptions, sessionId));
}
return createOkResponse(queryResultList);
} else {
return createOkResponse(alignmentStorageManager.query(studyStr, fileIdStr, query, queryOptions, sessionId));
}
} catch (Exception e) {
return createErrorResponse(e);
}
}
@GET
@Path("/stats")
@ApiOperation(value = "Fetch the stats of an alignment file", position = 15, response = AlignmentGlobalStats.class)
public Response getStats(@ApiParam(value = "Id of the alignment file in catalog", required = true) @QueryParam("file")
String fileIdStr,
@ApiParam(value = "(DEPRECATED) Study id", hidden = true) @QueryParam("studyId") String studyId,
@ApiParam(value = "Study [[user@]project:]study where study and project can be either the id or alias")
@QueryParam("study") String studyStr,
@ApiParam(value = "Comma separated list of regions 'chr:start-end'", required = false) @QueryParam("region") String region,
@ApiParam(value = "Minimum mapping quality", required = false) @QueryParam("minMapQ") Integer minMapQ,
@ApiParam(value = "Only alignments completely contained within boundaries of region", required = false)
@QueryParam("contained") Boolean contained) {
try {
if (StringUtils.isNotEmpty(studyId)) {
studyStr = studyId;
}
Query query = new Query();
query.putIfNotNull(AlignmentDBAdaptor.QueryParams.MIN_MAPQ.key(), minMapQ);
QueryOptions queryOptions = new QueryOptions();
queryOptions.putIfNotNull(AlignmentDBAdaptor.QueryParams.CONTAINED.key(), contained);
AlignmentStorageManager alignmentStorageManager = new AlignmentStorageManager(catalogManager, storageEngineFactory);
if (StringUtils.isNotEmpty(region)) {
String[] regionList = region.split(",");
List<QueryResult<AlignmentGlobalStats>> queryResultList = new ArrayList<>(regionList.length);
for (String regionAux : regionList) {
query.putIfNotNull(AlignmentDBAdaptor.QueryParams.REGION.key(), regionAux);
queryResultList.add(alignmentStorageManager.stats(studyStr, fileIdStr, query, queryOptions, sessionId));
}
return createOkResponse(queryResultList);
} else {
return createOkResponse(alignmentStorageManager.stats(studyStr, fileIdStr, query, queryOptions, sessionId));
}
// String userId = catalogManager.getUserManager().getId(sessionId);
// Long fileId = catalogManager.getFileManager().getId(userId, fileIdStr);
//
// Query query = new Query();
// query.putIfNotNull(AlignmentDBAdaptor.QueryParams.REGION.key(), region);
// query.putIfNotNull(AlignmentDBAdaptor.QueryParams.MIN_MAPQ.key(), minMapQ);
//
// QueryOptions queryOptions = new QueryOptions();
// queryOptions.putIfNotNull(AlignmentDBAdaptor.QueryParams.CONTAINED.key(), contained);
//
// QueryOptions options = new QueryOptions(QueryOptions.INCLUDE, FileDBAdaptor.QueryParams.URI.key());
// QueryResult<File> fileQueryResult = catalogManager.getFileManager().get(fileId, options, sessionId);
//
// if (fileQueryResult != null && fileQueryResult.getNumResults() != 1) {
// // This should never happen
// throw new CatalogException("Critical error: File " + fileId + " could not be found in catalog.");
// }
// String path = fileQueryResult.first().getUri().getRawPath();
//
// AlignmentStorageEngine alignmentStorageManager = storageManagerFactory.getAlignmentStorageManager();
// AlignmentGlobalStats stats = alignmentStorageManager.getDBAdaptor().stats(path, query, queryOptions);
// QueryResult<AlignmentGlobalStats> queryResult = new QueryResult<>("get stats", -1, 1, 1, "", "", Arrays.asList(stats));
// return createOkResponse(queryResult);
} catch (Exception e) {
return createErrorResponse(e);
}
}
@GET
@Path("/coverage")
@ApiOperation(value = "Fetch the coverage of an alignment file", position = 15, response = RegionCoverage.class)
public Response getCoverage(@ApiParam(value = "Id of the alignment file in catalog", required = true) @QueryParam("file")
String fileIdStr,
@ApiParam(value = "(DEPRECATED) Study id", hidden = true) @QueryParam("studyId") String studyId,
@ApiParam(value = "Study [[user@]project:]study where study and project can be either the id or alias")
@QueryParam("study") String studyStr,
@ApiParam(value = "Comma separated list of regions 'chr:start-end'", required = false) @QueryParam("region")
String region,
@ApiParam(value = "Minimum mapping quality", required = false) @QueryParam("minMapQ") Integer minMapQ,
@ApiParam(value = "Window size", required = false, defaultValue = "1") @QueryParam("windowSize")
Integer windowSize,
@ApiParam(value = "Only alignments completely contained within boundaries of region", required = false)
@QueryParam("contained") Boolean contained) {
try {
if (StringUtils.isNotEmpty(studyId)) {
studyStr = studyId;
}
Query query = new Query();
query.putIfNotNull(AlignmentDBAdaptor.QueryParams.MIN_MAPQ.key(), minMapQ);
QueryOptions queryOptions = new QueryOptions();
queryOptions.putIfNotNull(AlignmentDBAdaptor.QueryParams.CONTAINED.key(), contained);
queryOptions.putIfNotNull(AlignmentDBAdaptor.QueryParams.WINDOW_SIZE.key(), windowSize);
AlignmentStorageManager alignmentStorageManager = new AlignmentStorageManager(catalogManager, storageEngineFactory);
if (StringUtils.isNotEmpty(region)) {
String[] regionList = region.split(",");
List<QueryResult<RegionCoverage>> queryResultList = new ArrayList<>(regionList.length);
for (String regionAux : regionList) {
query.putIfNotNull(AlignmentDBAdaptor.QueryParams.REGION.key(), regionAux);
queryResultList.add(alignmentStorageManager.coverage(studyStr, fileIdStr, query, queryOptions, sessionId));
}
return createOkResponse(queryResultList);
} else {
return createOkResponse(alignmentStorageManager.coverage(studyStr, fileIdStr, query, queryOptions, sessionId));
}
} catch (Exception e) {
return createErrorResponse(e);
}
}
}