js.ontology-service-result.js Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of molgenis-ontology Show documentation
Show all versions of molgenis-ontology Show documentation
Plugin module containing SORTA (system for ontology-based re-coding and technical
annotation)
plugins.
(function ($, molgenis) {
"use strict";
var restApi = new molgenis.RestClient();
var ontologyServiceRequest = null;
var result_container = null;
var reserved_identifier_field = 'identifier';
var NO_MATCH_INFO = 'N/A';
var itermsPerPage = 5;
molgenis.OntologyService = function OntologySerivce(container, request) {
if (container) {
result_container = container;
}
if (request) {
ontologyServiceRequest = request;
ontologyServiceRequest.entityPager = {'start': 0, 'num': itermsPerPage, 'total': 5};
}
};
molgenis.OntologyService.prototype.renderPage = function () {
var items = [];
items.push('');
items.push('');
items.push('The total number of matched items is ');
items.push('');
items.push('
');
items.push('');
items.push('The total number of unmatched items is ');
items.push('');
items.push('
');
items.push('');
items.push('');
items.push('');
items.push('');
result_container.empty().append(items.join(''));
getMatchResultCount(function (data) {
var page = {};
var totalMatched = data.numberOfMatched;
var totalUnMatched = data.numberOfUnmatched;
page.total = ontologyServiceRequest.matched ? totalMatched : totalUnMatched;
updatePageFunction(page);
$('#matched-item-count').html(totalMatched);
$('#unmatched-item-count').html(totalUnMatched);
});
$('#sorta-download-button').click(function () {
$(this).parents('form:eq(0)').attr({
'action': molgenis.getContextUrl() + '/match/download/' + ontologyServiceRequest.sortaJobExecutionId,
'method': 'GET'
}).submit();
});
$('#matched-result-button').click(function () {
ontologyServiceRequest.matched = true;
molgenis.OntologyService.prototype.renderPage();
});
$('#unmatched-result-button').click(function () {
ontologyServiceRequest.matched = false;
molgenis.OntologyService.prototype.renderPage();
});
function getMatchResultCount(callback) {
$.ajax({
type: 'GET',
url: molgenis.getContextUrl() + '/count/' + ontologyServiceRequest.sortaJobExecutionId,
contentType: 'application/json',
success: function (data) {
if (callback !== null && typeof callback === 'function') {
callback(data)
}
}
});
}
};
function updatePageFunction(page) {
$.extend(ontologyServiceRequest.entityPager, page);
$.ajax({
type: 'POST',
url: molgenis.getContextUrl() + '/match/retrieve',
async: false,
data: JSON.stringify(ontologyServiceRequest),
contentType: 'application/json',
success: function (data) {
var table_container = $('').addClass('col-md-12');
if (data.items.length > 0) {
var pagerDiv = $('').addClass('row').appendTo(table_container);
var searchItems = [];
searchItems.push('');
searchItems.push('Filter');
searchItems.push('');
searchItems.push('')
searchItems.push('')
var matchResultHeaderDiv = $('').addClass('row').css({'margin-bottom': '10px'}).appendTo(table_container);
matchResultHeaderDiv.append(searchItems.join(''));
matchResultHeaderDiv.append('' + (ontologyServiceRequest.matched ? 'Matched result' : 'Unmatched result') + '
');
var tableItems = [];
tableItems.push('');
tableItems.push('Input term Best candidate Score Manual Match ' + (ontologyServiceRequest.matched ? 'Remove ' : '') + ' ');
tableItems.push('
');
$('').addClass('row').append(tableItems.join('')).appendTo(table_container);
var table = $(table_container).find('table:eq(0)')
$.each(data.items, function (index, entity) {
table.append(createRowForMatchedTerm(entity, ontologyServiceRequest.matched, page));
});
var searchButton = matchResultHeaderDiv.find('button:eq(0)');
var searchBox = matchResultHeaderDiv.find('input:eq(0)');
$(searchButton).click(function () {
if (ontologyServiceRequest.filterQuery !== $(searchBox).val()) {
ontologyServiceRequest.filterQuery = $(searchBox).val();
updatePageFunction(page);
}
return false;
});
$(searchBox).keyup(function (e) {
//stroke key enter or backspace
if (e.keyCode === 13 || $(this).val() === '') {
$(searchButton).click();
}
});
$(pagerDiv).pager({
'page': Math.floor(data.start / data.num) + (data.start % data.num == 0 ? 0 : 1) + 1,
'nrItems': data.total,
'nrItemsPerPage': data.num,
'onPageChange': updatePageFunction
});
} else {
var messageItems = [];
messageItems.push('There are no results!
');
if (ontologyServiceRequest.filterQuery) {
messageItems.push('Clear the query : ' + ontologyServiceRequest.filterQuery + ' ');
messageItems.push('');
}
messageItems.push('
');
table_container.append(messageItems.join(''));
$(table_container).find('span.glyphicon-remove:eq(0)').click(function () {
ontologyServiceRequest.filterQuery = '';
updatePageFunction(page);
});
}
//Remove the existing results
result_container.children('div.row:gt(0)').empty();
//Add the new results to the page
$('').addClass('row').append(table_container).appendTo(result_container);
}
});
};
molgenis.OntologyService.prototype.deleteMatchingTask = function (sortaJobExecutionId, callback) {
$.ajax({
type: 'POST',
url: molgenis.getContextUrl() + '/delete',
async: false,
data: JSON.stringify(sortaJobExecutionId),
contentType: 'application/json',
success: function () {
if (callback) callback();
}
});
};
function createRowForMatchedTerm(responseData, matched, page) {
var row = $(' ');
row.append(gatherInputInfoHelper(responseData.inputTerm));
row.append(gatherOntologyInfoHelper(responseData.inputTerm, responseData.ontologyTerm));
$(' ').append(responseData.matchedTerm.score ? responseData.matchedTerm.score.toFixed(2) + '%' : NO_MATCH_INFO).appendTo(row);
if (matched) {
$(' ').append('').appendTo(row);
$(' ').append(responseData.matchedTerm.validated ? '' : '').appendTo(row);
row.find('button:eq(0)').click(function () {
matchEntity(responseData.inputTerm.Identifier, ontologyServiceRequest.sortaJobExecutionId, function (data) {
var updatedMappedEntity = {};
$.map(responseData.matchedTerm, function (val, key) {
if (key !== 'identifier') updatedMappedEntity[key] = val;
if (key === 'validated') updatedMappedEntity[key] = false;
if (key === 'inputTerm') updatedMappedEntity[key] = val.Identifier;
});
if (data.ontologyTerms && data.ontologyTerms.length > 0) {
var ontologyTerm = data.ontologyTerms[0];
updatedMappedEntity['score'] = ontologyTerm.Score;
updatedMappedEntity['matchTerm'] = ontologyTerm.ontologyTermIRI;
} else {
updatedMappedEntity['score'] = 0;
updatedMappedEntity['matchTerm'] = null;
}
restApi.update('/api/v1/' + ontologyServiceRequest.sortaJobExecutionId + '/' + responseData.matchedTerm.identifier, updatedMappedEntity, createCallBackFunction(), true);
});
});
} else {
var button = $('').click(function () {
matchEntity(responseData.inputTerm.Identifier, ontologyServiceRequest.sortaJobExecutionId, function (data) {
createTableForCandidateMappings(responseData.inputTerm, data, row, page);
})
});
$(' ').append(button).appendTo(row);
}
return row;
}
function createTableForCandidateMappings(inputEntity, data, row, page) {
if (data.message) {
console.log('Error fetching candidate mappings', data.message);
throw data.message;
}
var container = $('').css({'margin-bottom': '20px'});
//Hide existing table
row.parents('table:eq(0)').hide();
//Add table containing candidate matches to the view
row.parents('div:eq(0)').append(container);
//Add a backButton for users to go back to previous summary table
var backButton = $('').css({
'margin-bottom': '10px',
'float': 'right'
}).click(function () {
container.remove();
row.parents('table:eq(0)').show();
});
//Add a unknownButton for users to choose 'Unknown' for the input term
var unknownButton = $('').css({
'margin-bottom': '10px',
'margin-right': '10px',
'float': 'right'
}).click(function () {
getMappingEntity(inputEntity.Identifier, ontologyServiceRequest.sortaJobExecutionId, function (data) {
if (data.items.length > 0) {
var mappedEntity = data.items[0];
var href = '/api/v1/' + ontologyServiceRequest.sortaJobExecutionId + '/' + mappedEntity.identifier;
var updatedMappedEntity = {};
$.map(mappedEntity, function (val, key) {
updatedMappedEntity[key] = val;
if (key === 'validated') updatedMappedEntity[key] = true;
if (key === 'inputTerm') {
console.log('inputTerm', val)
updatedMappedEntity[key] = val.Identifier;
}
if (key === 'score') updatedMappedEntity[key] = 0;
if (key === 'matchTerm') updatedMappedEntity[key] = null;
});
restApi.update(href, updatedMappedEntity, createCallBackFunction(), true);
}
});
});
var hoverover = $('Adjusted score ?').css({'cursor': 'pointer'}).popover({
'title': 'Explanation',
'content': 'Adjusted scores are derived from the original scores (lexical similarity) combined with the weight of the words (inverse document frequency)
',
'placement': 'auto',
'trigger': 'hover',
'html': true
});
var table = $('
');
var header = $(' ').appendTo(table);
$(' ').append('Input term').css({'width': '30%'}).appendTo(header);
$(' ').append('Candidate mapping').css({'width': '40%'}).appendTo(header);
$(' ').append('Score').css({'width': '12%'}).appendTo(header);
$(' ').append(hoverover).css({'width': '12%'}).appendTo(header);
$(' ').append('Select').appendTo(header);
var hintInformation;
if (data.ontologyTerms && data.ontologyTerms.length > 0) {
hintInformation = $('The candidate ontology terms are sorted based on similarity score, please select one of them by clicking button
');
$.each(data.ontologyTerms, function (index, ontologyTerm) {
if (index >= 20) return;
var row = $(' ').appendTo(table);
row.append(index == 0 ? gatherInputInfoHelper(inputEntity) : ' ');
row.append(gatherOntologyInfoHelper(inputEntity, ontologyTerm));
row.append('' + ontologyTerm.Score.toFixed(2) + '% ');
row.append('' + ontologyTerm.Combined_Score.toFixed(2) + '% ');
row.append(' ');
row.data('ontologyTerm', ontologyTerm);
row.find('button:eq(0)').click(function () {
getMappingEntity(inputEntity.Identifier, ontologyServiceRequest.sortaJobExecutionId, function (data) {
if (data.items.length > 0) {
var mappedEntity = data.items[0];
var href = '/api/v1/' + ontologyServiceRequest.sortaJobExecutionId + '/' + mappedEntity.identifier;
var updatedMappedEntity = {};
$.map(mappedEntity, function (val, key) {
if (key === 'validated') updatedMappedEntity[key] = true;
else if (key === 'inputTerm') updatedMappedEntity[key] = val.Identifier;
else if (key === 'matchTerm') updatedMappedEntity.matchTerm = row.data('ontologyTerm').ontologyTermIRI;
else if (key === 'score') updatedMappedEntity.score = row.data('ontologyTerm').Score;
else updatedMappedEntity[key] = val;
});
restApi.update(href, updatedMappedEntity, createCallBackFunction(), true);
}
});
});
});
} else {
hintInformation = $('There are no candidate mappings for this input term!
');
$(' ').append(gatherInputInfoHelper(inputEntity)).append('' + NO_MATCH_INFO + ' ' + NO_MATCH_INFO + ' ' + NO_MATCH_INFO + ' ' + NO_MATCH_INFO + ' ').appendTo(table);
}
$('').append(hintInformation).append(backButton).append(unknownButton).append(table).appendTo(container);
}
function createCallBackFunction() {
return {
'success': function () {
molgenis.OntologyService.prototype.renderPage();
}, 'error': function () {
molgenis.OntologyService.prototype.renderPage();
}
};
}
function getMappingEntity(inputTermIdentifier, sortaJobExecutionId, callback) {
restApi.getAsync('/api/v1/' + sortaJobExecutionId, {
'q': [{
'field': 'inputTerm',
'operator': 'EQUALS',
'value': inputTermIdentifier
}],
'expand': ['inputTerm']
}, function (data) {
if (callback) callback(data);
});
}
function matchEntity(inputTermIdentifier, sortaJobExecutionId, callback) {
$.ajax({
type: 'POST',
url: molgenis.getContextUrl() + '/match/entity',
async: false,
data: JSON.stringify({'identifier': inputTermIdentifier, 'sortaJobExecutionId': sortaJobExecutionId}),
contentType: 'application/json',
success: function (data) {
if (data.message) throw data.message;
if (callback) callback(data);
}
});
}
function gatherInputInfoHelper(inputTerm) {
var inputTermTd = $(' ');
if (inputTerm) {
$.map(inputTerm ? inputTerm : {}, function (val, key) {
if (key.toLowerCase() !== reserved_identifier_field.toLowerCase()) inputTermTd.append('' + key + ' : ' + val + '');
});
}
return inputTermTd;
}
function gatherOntologyInfoHelper(inputEntity, ontologyTerm) {
var ontologyTermTd = $(' ');
if (inputEntity && ontologyTerm) {
var synonymDiv = $('Synonym : ');
var synonyms = getOntologyTermSynonyms(ontologyTerm);
if (synonyms.length == 0) {
synonymDiv.append(NO_MATCH_INFO);
} else if (synonyms.length == 1) {
synonymDiv.append(synonyms.join());
} else {
synonymDiv.addClass('show-popover').append('' + synonyms.length + ' synonyms, see more details').popover({
'content': synonyms.join('
'),
'placement': 'auto',
'trigger': 'hover',
'html': true
});
}
//check if the ontologyTermIRI is a valid link
if (ontologyTerm.ontologyTermIRI.startsWith('http')) {
ontologyTermTd.append('').append(synonymDiv);
} else {
ontologyTermTd.append('Name : ' + ontologyTerm.ontologyTermName + '').append(synonymDiv);
}
var annotationMap = {};
$.each(ontologyTerm.ontologyTermDynamicAnnotation, function (i, annotation) {
if (!annotationMap[annotation.name]) {
annotationMap[annotation.name] = [];
}
annotationMap[annotation.name].push(annotation.value);
});
$.each(Object.keys(inputEntity), function (index, key) {
if (key.toLowerCase() !== 'name' && key.toLowerCase().search('synonym') === -1 && key.toLowerCase() !== reserved_identifier_field.toLowerCase()) {
ontologyTermTd.append('' + key + ' : ' + (annotationMap[key] ? annotationMap[key].join() : 'N/A') + '');
}
});
} else {
ontologyTermTd.append(NO_MATCH_INFO);
}
return ontologyTermTd;
}
function getOntologyTermSynonyms(ontologyTerm) {
var synonyms = [];
if (ontologyTerm.ontologyTermSynonym.length > 0) {
$.each(ontologyTerm.ontologyTermSynonym, function (index, ontologyTermSynonymEntity) {
if (ontologyTerm.ontologyTermName !== ontologyTermSynonymEntity.ontologyTermSynonym && $.inArray(ontologyTermSynonymEntity.ontologyTermSynonym, synonyms) === -1) {
synonyms.push(ontologyTermSynonymEntity.ontologyTermSynonym);
}
});
}
return synonyms;
}
}($, window.top.molgenis = window.top.molgenis || {}));