-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
57 changed files
with
1,775 additions
and
292 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
{ | ||
"presets": ["es2015"] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
/* global ReactDOM */ | ||
|
||
// This is the react template,called from showMessageDialog later | ||
function MessageDialog(props) { | ||
return ( | ||
<div className={"alert alert-dismissable " + props.type} role="alert"> | ||
<button type="button" className="close" aria-label="Close" onClick={() => {removeMessageDialog(props.id)}}> | ||
<span aria-hidden="true">×</span> | ||
</button> | ||
{props.message} | ||
</div> | ||
) | ||
} | ||
|
||
class MessageArea extends React.Component { | ||
render() { | ||
const messageDialogs = this.props.messages.map((element) => { | ||
return <MessageDialog type={element.type} message={element.message} key={element.key} id={element.key}/> | ||
}); | ||
return <div>{messageDialogs}</div> | ||
} | ||
} | ||
|
||
/** | ||
* This function generates consecutive uids starting from 0 | ||
*/ | ||
var uid = (() => { | ||
var id=0; | ||
return () => id++; | ||
})(); | ||
|
||
let messages = []; | ||
|
||
/** | ||
* This function appends a bootstrap dialog to the message area with the given message and type | ||
* @param {type} message - The text that should be shown in the dialog | ||
* @param {type} type - The type (color) of the dialog. Possible values: alert-success, alert-warning, alert-danger, alert-info (default) | ||
* @returns {void} | ||
*/ | ||
function showMessageDialog(message, type){ | ||
var knownTypes = ['alert-success', 'alert-warning', 'alert-danger', 'alert-info']; | ||
if(knownTypes.indexOf(type) === -1){ | ||
var shortTypes = ['success', 'warning', 'danger', 'info']; | ||
if(shortTypes.indexOf(type) === -1){ | ||
type = 'alert-info'; | ||
} else { | ||
type = "alert-" + type; | ||
} | ||
} | ||
messages.push({message: message, type: type, key: uid()}); | ||
updateMessageDialogs(); | ||
} | ||
|
||
function removeMessageDialog(key) { | ||
messages = messages.filter(message => message.key !== key); | ||
updateMessageDialogs(); | ||
} | ||
|
||
function updateMessageDialogs() { | ||
ReactDOM.render( | ||
<MessageArea messages={messages}/>, | ||
document.getElementById('global-message-area') | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
/* global dbversion */ | ||
/* global biom */ | ||
/* global internalProjectId */ | ||
/* global blackbirdPreviewPath */ | ||
$('document').ready(function () { | ||
// Set header of page to project-id | ||
$('.page-header').text(biom.id); | ||
|
||
// Fill overview table with values | ||
$('#project-overview-table-id').text(biom.id); | ||
$('#project-overview-table-comment').text(biom.comment); | ||
$('#project-overview-table-rows').text(biom.shape[0]); | ||
$('#project-overview-table-cols').text(biom.shape[1]); | ||
$('#project-overview-table-nnz').text(biom.nnz + " (" + (100 * biom.nnz / (biom.shape[0] * biom.shape[1])).toFixed(2) + "%)"); | ||
|
||
// Set action if edit dialog is shown | ||
$('#editProjectDialog').on('shown.bs.modal', function () { | ||
$('#editProjectDialogProjectID').val(biom.id); | ||
$('#editProjectDialogComment').val(biom.comment); | ||
$('#editProjectDialogProjectID').focus(); | ||
}); | ||
|
||
// Set action if edit dialog is saved | ||
$('#editProjectDialogSaveButton').click(function () { | ||
biom.id = $('#editProjectDialogProjectID').val(); | ||
biom.comment = $('#editProjectDialogComment').val(); | ||
saveBiomToDB(); | ||
}); | ||
|
||
$('#project-export-as-biom-v1').click(() => { | ||
exportProjectAsBiom(); | ||
}); | ||
|
||
}); | ||
|
||
/** | ||
* Saves the current value of the global biom variable to the postgres database | ||
*/ | ||
function saveBiomToDB() { | ||
biom.write().then(function (biomJson) { | ||
var webserviceUrl = Routing.generate('api', {'namespace': 'edit', 'classname': 'updateProject'}); | ||
$.ajax(webserviceUrl, { | ||
data: { | ||
"dbversion": dbversion, | ||
"project_id": internalProjectId, | ||
"biom": biomJson | ||
}, | ||
method: "POST", | ||
success: function () { | ||
location.reload(); | ||
} | ||
}); | ||
}, function (failure) { | ||
console.log(failure); | ||
}); | ||
} | ||
|
||
function exportProjectAsBiom() { | ||
biom.write().then(function (biomJson) { | ||
var blob = new Blob([biomJson], {type: "text/plain"}); | ||
saveAs(blob, biom.id+".json"); | ||
}, function (failure) { | ||
console.log(failure); | ||
}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,145 @@ | ||
/* global dbversion */ | ||
/* global biom */ | ||
/* global _ */ | ||
$('document').ready(() => { | ||
// Calculate values for mapping overview table | ||
let sampleOrganismIDs = biom.getMetadata({dimension: 'columns', attribute: ['fennec', dbversion, 'organism_id']}).filter(element => element !== null); | ||
let otuOrganismIDs = biom.getMetadata({dimension: 'rows', attribute: ['fennec', dbversion, 'organism_id']}).filter(element => element !== null); | ||
var mappedSamples = sampleOrganismIDs.length; | ||
var percentageMappedSamples = 100 * mappedSamples / biom.shape[1]; | ||
var mappedOTUs = otuOrganismIDs.length; | ||
var percentageMappedOTUs = 100 * mappedOTUs / biom.shape[0]; | ||
|
||
// Add values to mapping overview table | ||
$('#mapping-otu').text(mappedOTUs); | ||
$('#progress-bar-mapping-otu').css('width', percentageMappedOTUs + '%').attr('aria-valuenow', percentageMappedOTUs); | ||
$('#progress-bar-mapping-otu').text(percentageMappedOTUs.toFixed(0) + '%'); | ||
$('#mapping-sample').text(mappedSamples); | ||
$('#progress-bar-mapping-sample').css('width', percentageMappedSamples + '%').attr('aria-valuenow', percentageMappedSamples); | ||
$('#progress-bar-mapping-sample').text(percentageMappedSamples.toFixed(0) + '%'); | ||
|
||
// Add semi-global dimension variable (stores last mapped dimension) | ||
var dimension = 'rows'; | ||
var method = 'ncbi_taxid'; | ||
|
||
// Set action for click on mapping "GO" button | ||
$('#mapping-action-button').on('click', function () { | ||
dimension = $('#mapping-dimension-select').val(); | ||
method = $('#mapping-method-select').val(); | ||
let ids = getIdsForMethod(method, dimension); | ||
let uniq_ids = ids.filter(value => value !== null); | ||
uniq_ids = _.uniq(uniq_ids); | ||
$('#mapping-action-busy-indicator').show(); | ||
$('#mapping-results-section').hide(); | ||
if (uniq_ids.length === 0) { | ||
handleMappingResult(dimension, ids, [], method); | ||
} else { | ||
var webserviceUrl = getWebserviceUrlForMethod(method); | ||
$.ajax(webserviceUrl, { | ||
data: { | ||
dbversion: dbversion, | ||
ids: uniq_ids | ||
}, | ||
method: 'POST', | ||
success: function (data) { | ||
handleMappingResult(dimension, ids, data, method); | ||
} | ||
}); | ||
} | ||
}); | ||
|
||
/** | ||
* Returns the array with search id for the respective method in the given dimension | ||
* @param method | ||
* @param dimension | ||
* @return {Array} | ||
*/ | ||
function getIdsForMethod(method, dimension) { | ||
let ids = []; | ||
if(method === 'ncbi_taxid'){ | ||
ids = biom.getMetadata({dimension: dimension, attribute: 'ncbi_taxid'}); | ||
} else if(method === 'organism_name'){ | ||
ids = biom[dimension].map((element) => element.id); | ||
} | ||
return ids; | ||
} | ||
|
||
/** | ||
* Returns the webserviceUrl for the given mapping method | ||
* @param method | ||
* @return {string} | ||
*/ | ||
function getWebserviceUrlForMethod(method) { | ||
let method2service = { | ||
'ncbi_taxid': 'byNcbiTaxid', | ||
'organism_name': 'byOrganismName' | ||
}; | ||
let webserviceUrl = Routing.generate('api', {'namespace': 'mapping', 'classname': method2service[method]}); | ||
return webserviceUrl; | ||
} | ||
|
||
/** | ||
* Returns a string representation for the IDs used for mapping in the chosen method | ||
* @param method | ||
* @return {string} | ||
*/ | ||
function getIdStringForMethod(method) { | ||
let idString = ""; | ||
if (method === 'ncbi_taxid'){ | ||
idString = "NCBI taxid"; | ||
} else if (method === 'organism_name') { | ||
idString = "Organism name"; | ||
} | ||
return idString; | ||
} | ||
|
||
/** | ||
* Create the results component from the returned mapping and store result in global biom object | ||
* @param {string} dimension | ||
* @param {Array} idsFromBiom those are the ids used for mapping in the order they appear in the biom file | ||
* @param {Array} mapping from ids to organism_ids as returned by webservice | ||
* @param {string} method of mapping | ||
*/ | ||
function handleMappingResult(dimension, idsFromBiom, mapping, method) { | ||
let organism_ids = new Array(idsFromBiom.length).fill(null); | ||
var idsFromBiomNotNullCount = 0; | ||
var idsFromBiomMappedCount = 0; | ||
for (let i = 0; i < idsFromBiom.length; i++) { | ||
if (idsFromBiom[i] !== null) { | ||
idsFromBiomNotNullCount++; | ||
if (idsFromBiom[i] in mapping && mapping[idsFromBiom[i]] !== null) { | ||
idsFromBiomMappedCount++; | ||
organism_ids[i] = mapping[idsFromBiom[i]]; | ||
} | ||
} | ||
} | ||
biom.addMetadata({dimension: dimension, attribute: ['fennec', dbversion, 'organism_id'], values: organism_ids}); | ||
biom.addMetadata({dimension: dimension, attribute: ['fennec', dbversion, 'assignment_method'], defaultValue: method}); | ||
var idString = getIdStringForMethod(method); | ||
$('#mapping-action-busy-indicator').hide(); | ||
$('#mapping-results-section').show(); | ||
$('#mapping-results').text(`From a total of ${idsFromBiom.length} organisms: ${idsFromBiomNotNullCount} have a ${idString}, of which ${idsFromBiomMappedCount} could be mapped to organism_ids.`); | ||
} | ||
|
||
// Set action for click on mapping "Save to database" button | ||
$('#mapping-save-button').on('click', function () { | ||
saveBiomToDB(); | ||
}); | ||
|
||
// Set action for click on mapping "Download as csv" button | ||
$('#mapping-download-csv-button').on('click', function () { | ||
var ids = biom[dimension].map(function (element) { | ||
return element.id; | ||
}); | ||
var ids = getIdsForMethod(method, dimension); | ||
var fennec_id = biom.getMetadata({dimension: dimension, attribute: ['fennec', dbversion, 'organism_id']}); | ||
var id_header = dimension === 'rows' ? 'OTU_ID' : 'Sample_ID'; | ||
let idString = getIdStringForMethod(method); | ||
var csv = `${id_header}\t${idString}\tFennec_ID\n`; | ||
for(var i=0; i<ids.length; i++){ | ||
csv += ids[i]+"\t"+ids[i]+"\t"+fennec_id[i]+"\n"; | ||
} | ||
var blob = new Blob([csv], {type: "text/plain;charset=utf-8"}); | ||
saveAs(blob, "mapping.csv"); | ||
}); | ||
}); |
Oops, something went wrong.