Commit 4817ee85 authored by Severine Duvaud's avatar Severine Duvaud
Browse files

First attempt to implement Beacon version 0.3 Updated query parameters...

First attempt to implement Beacon version 0.3 Updated query parameters (Caution: datasetIds + referenceBase + alternateBase still missing)
parent 94103b7e
var beacon = {};
beacon.info = require('./beacon-info.js').info
beacon.checkResultAndGetResponse = require('./beacon-query.js').checkResultAndGetResponse
beacon.checkPreconditions = require('./beacon-query.js').checkPreconditions
beacon.buildMongoQuery = require('./beacon-query.js').buildMongoQuery
module.exports = beacon;
\ No newline at end of file
This diff is collapsed.
var info = require('./beacon-info.js').info
//check https://genome.ucsc.edu/FAQ/FAQreleases.html
var referenceMap = {
'GRCh38': 'SEGMENTS_HG38',
'GRCh37': 'SEGMENTS_HG19',
'GRCh36': 'SEGMENTS_HG18'
};
//correspondence to arraymap class
var variantClassMap = {
"DEL": -1,
"DUP": 1
};
// By default doe Maximilien takes Reference 37. https://github.com/maximilianh/ucscBeacon/blob/master/help.txt
//TODO Should it be the same as Maximilen? Is it specified by beacon documentaiton?
var defaultReference = 'GRCh36';
function checkPreconditions(params) {
if (!params.referenceName) {
return {
hasError: true,
msg: "reference name is not present"
};
}
var referenceNameInvalid = {
hasError: true,
msg: params.referenceName + " reference name not valid"
};
if (Number(params.referenceName)) {
if (params.referenceName < 1 || params.referenceName > 23) {
return referenceNameInvalid;
}
}
else {
if (params.referenceName.match(/^(X|Y)$/i) == null) {
return referenceNameInvalid;
}
}
if (!params.start) {
return {
hasError: true,
msg: "position not present"
};
}
if (!Number(params.start)) {
return {
hasError: true,
msg: "position not a number"
};
}
console.log(Boolean(variantClassMap[params.variantClass]));
if (!params.variantClass) {
return {
hasError: true,
msg: "variant class is not defined, arrayMap supports be DUP or DEL"
};
}
if (!variantClassMap[params.variantClass]) {
return {
hasError: true,
msg: params.variantClass + " variant class is not supported by arrayMap , only supports DUP or DEL"
};
} //TODO add additional checks
return {
hasError: false
};
}
function buildMongoQuery(params) {
var position = parseInt(params.start);
var conditions = [];
//add constraint on dataset if it exsits
if (params.dataset) conditions.push({
ICDMORPHOLOGYCODE: params.dataset
});
var segType = variantClassMap[params.variantClass]
var convertedReference = referenceMap[params.assemblyId || defaultReference];
var cond = {};
cond[convertedReference] = {
'$elemMatch': {
'CHRO': params.referenceName,
'SEGTYPE': segType,
'SEGSTOP': {
$gte: position
},
'SEGSTART': {
$lte: position
}
}
}
conditions.push(cond);
return {
$and: conditions
};
}
function checkResultAndGetResponse(params, samples, countTotal) {
var responseResource = {
"exists": null,
"info": "ok",
"error": null
}
if (samples && samples.length > 0) { // a value was found by mongodb
responseResource.observed = samples.length;
var matchedSegments = samples.map(function (s) { return checkResult(params, s)});
if (!matchedSegments || !matchedSegments[0] || !matchedSegments[0].matchedSegment) {
responseResource.exists = null;
responseResource.error = "Internal error, DB returned a value but post check is not valid."
} else {
responseResource.exists = "overlap";
responseResource.NOT_BEACON_ARRAYMAP_DEBUG_INFO = {"matchedSegments" : matchedSegments};
}
}
var queryResource = {
"referenceName": params.referenceName,
"start": params.start,
"assemblyId": params.assemblyId,
"datasetid": params.dataset
};
return {
"beacon_id": info.id,
"response": responseResource,
"query": queryResource
};
}
function checkResult(params, sample) {
var convertedReference = referenceMap[params.reference || defaultReference];
var expectedSegType = variantClassMap[params.variantClass]
var position = parseInt(params.start);
//TODO should check for dataset and genomre reference as well
var foundSegment;
sample[convertedReference].forEach(function (segment) {
if (segment.CHRO === params.referenceName) {
var posStart = parseInt(segment.SEGSTART);
var posStop = parseInt(segment.SEGSTOP);
var segType = parseInt(segment.SEGTYPE);
if ((segType == expectedSegType) && (posStart <= position) && (position <= posStop)) {
foundSegment = segment;
return; //exit loop
}
}
})
var result = {
matchedSampleUID: sample.UID,
matchedDataSet: sample.ICDMORPHOLOGYCODE,
matchedSegment: foundSegment
}
return result;
}
module.exports.checkPreconditions = checkPreconditions;
module.exports.buildMongoQuery = buildMongoQuery;
module.exports.checkResultAndGetResponse = checkResultAndGetResponse;
\ No newline at end of file
var express = require('express');
var router = express.Router();
var beacon = require('../arraymap-beacon/v0.2/arraymap-beacon.js');
var _ = require('underscore')
/* GET home page. */
......@@ -43,7 +42,7 @@ router.get('/samples/', function (req, res) {
/* Returns response for API v 0.2 */
router.get('/v0.2/query/', function (req, res) {
var beacon = require('../arraymap-beacon/v0.2/arraymap-beacon.js');
var preconditions = beacon.checkPreconditions(req.query);
if (preconditions.hasError) {
......@@ -65,5 +64,30 @@ router.get('/v0.2/query/', function (req, res) {
});
/* Returns response for API v 0.2 */
router.get('/v0.3/query/', function (req, res) {
var beacon = require('../arraymap-beacon/v0.3/arraymap-beacon.js');
var preconditions = beacon.checkPreconditions(req.query);
if (preconditions.hasError) {
res.json(preconditions.msg); //Gets error messages
return;
}
var mongoQuery = beacon.buildMongoQuery(req.query);
console.log("Building MongoDB query params: " + JSON.stringify(mongoQuery));
req.db.samples.count({'ICDMORPHOLOGYCODE': req.query.dataset}, function(err, count){
req.db.samples.find(mongoQuery, {}, function (err, docs){
var response = beacon.checkResultAndGetResponse(req.query, docs, count);
response.NOT_BEACON_totalInDataSet = count;
res.json(response);
});
}
)
});
module.exports = router;
\ No newline at end of file
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment