morpheus.OpenFileTool = function(options) { this.options = options || {}; }; morpheus.OpenFileTool.prototype = { toString : function() { return 'Open File'; }, gui : function() { var array = [ { name : 'open_file_action', value : 'open', type : 'bootstrap-select', options : [ { name : 'Annotate columns', value : 'Annotate Columns' }, { name : 'Annotate rows', value : 'Annotate Rows' }, { divider : true }, { name : 'Append rows to current dataset', value : 'append' }, { name : 'Append columns to current dataset', value : 'append columns' }, { name : 'Overlay onto current dataset', value : 'overlay' }, { name : 'Open dataset in new tab', value : 'open' }, { divider : true }, { name : 'Open dendrogram', value : 'Open dendrogram' } ] } ]; if (this.options.file == null) { array.push({ name : 'file', showLabel : false, placeholder : 'Open your own file', value : '', type : 'file', required : true, help : morpheus.DatasetUtil.DATASET_FILE_FORMATS }); } array.options = { ok : this.options.file != null, size : 'modal-lg' }; return array; }, init : function(project, form, initOptions) { form.$form.find('[name=open_file_action]').on( 'change', function(e) { var action = $(this).val(); if (action === 'append columns' || action === 'append' || action === 'open' || action === 'overlay') { form.setHelpText('file', morpheus.DatasetUtil.DATASET_FILE_FORMATS); } else if (action === 'Open dendrogram') { form.setHelpText('file', morpheus.DatasetUtil.DENDROGRAM_FILE_FORMATS); } else { form.setHelpText('file', morpheus.DatasetUtil.ANNOTATION_FILE_FORMATS); } }); if (this.options.file == null) { $('

Use your own file

').insertAfter( form.$form.find('.form-group:first')); var _this = this; var id = _.uniqueId('morpheus'); form.$form .append('

'); var $sampleDatasets = $('
'); form.$form.append($sampleDatasets); var sampleDatasets = new morpheus.SampleDatasets({ $el : $sampleDatasets, callback : function(heatMapOptions) { form.setValue('file', heatMapOptions.dataset); _this.ok(); } }); } form.on('change', function(e) { var value = e.value; if (value !== '' && value != null) { form.setValue('file', value); _this.ok(); } }); }, execute : function(options) { var that = this; if (this.options.file) { options.input.file = this.options.file; } var project = options.project; if (options.input.open_file_action === 'append columns' || options.input.open_file_action === 'append' || options.input.open_file_action === 'open' || options.input.open_file_action === 'overlay') { new morpheus.OpenDatasetTool().execute(options); } else if (options.input.open_file_action === 'Open dendrogram') { morpheus.HeatMap.showTool(new morpheus.OpenDendrogramTool( options.input.file), options.controller); } else { // annotate rows or columns var controller = options.controller; var isAnnotateColumns = options.input.open_file_action == 'Annotate Columns'; var fileOrUrl = options.input.file; var dataset = project.getFullDataset(); var fileName = morpheus.Util.getFileName(fileOrUrl); if (morpheus.Util.endsWith(fileName, '.cls')) { var result = morpheus.Util.readLines(fileOrUrl); result.done(function(lines) { that.annotateCls(controller, dataset, fileName, isAnnotateColumns, lines); }); } else if (morpheus.Util.endsWith(fileName, '.gmt')) { morpheus.BufferedReader.getArrayBuffer(fileOrUrl, function(err, buf) { if (err) { throw new Error('Unable to read ' + fileOrUrl); } var sets = new morpheus.GmtReader() .read(new morpheus.BufferedReader(new Uint8Array( buf))); that.prompt(null, dataset, controller, isAnnotateColumns, sets); }); } else { var result = morpheus.Util.readLines(fileOrUrl); result.done(function(lines) { that.prompt(lines, dataset, controller, isAnnotateColumns, null); }); } } }, annotateCls : function(controller, dataset, fileName, isColumns, lines) { if (isColumns) { dataset = morpheus.DatasetUtil.transposedView(dataset); } var assignments = new morpheus.ClsReader().read(lines); if (assignments.length !== dataset.getRowCount()) { throw new Error( 'Number of samples in cls file does not match dataset.'); } var vector = dataset.getRowMetadata().add( morpheus.Util.getBaseFileName(fileName)); for (var i = 0; i < assignments.length; i++) { vector.setValue(i, assignments[i]); } if (controller) { controller.getProject().trigger('trackChanged', { vectors : [ vector ], render : [ 'color' ], columns : isColumns }); } }, /** * * @param lines * Lines of text in annotation file or null if a gmt file * @param dataset * Current dataset * @param isColumns * Whether annotating columns * @param sets * Sets if a gmt file or null * @param metadataName * The dataset metadata name to match on * @param fileColumnName * The metadata file name to match on * @param fileColumnNamesToInclude * An array of column names to include from the metadata file or * null to include all */ annotate : function(lines, dataset, isColumns, sets, metadataName, fileColumnName, fileColumnNamesToInclude) { if (isColumns) { dataset = morpheus.DatasetUtil.transposedView(dataset); } var vector = dataset.getRowMetadata().getByName(metadataName); if (!vector) { throw new Error('vector ' + metadataName + ' not found.'); } var vectors = []; var idToIndices = morpheus.VectorUtil.createValueToIndicesMap(vector); if (!lines) { _ .each( sets, function(set) { var name = set.name; var members = set.ids; // var v = dataset.getRowMetadata() // .getByName(name); // overwrite existing values // if (!v) { var v = dataset.getRowMetadata().add(name); // } vectors.push(v); _ .each( members, function(id) { var indices = idToIndices .get(id); if (indices !== undefined) { for (var i = 0, nIndices = indices.length; i < nIndices; i++) { v.setValue( indices[i], name); } } }); }); } else { var tab = /\t/; var header = lines[0].split(tab); var fileMatchOnColumnIndex = _.indexOf(header, fileColumnName); if (fileMatchOnColumnIndex === -1) { throw new Error(fileColumnName + ' not found in header:' + header); } var columnIndices = []; var nheaders = header.length; for (var j = 0; j < header.length; j++) { var name = header[j]; if (j === fileMatchOnColumnIndex) { continue; } if (fileColumnNamesToInclude && _.indexOf(fileColumnNamesToInclude, name) === -1) { continue; } var v = dataset.getRowMetadata().getByName(name); if (!v) { v = dataset.getRowMetadata().add(name); } columnIndices.push(j); vectors.push(v); } var nheaders = columnIndices.length; for (var i = 1, nrows = lines.length; i < nrows; i++) { var line = lines[i].split(tab); var id = line[fileMatchOnColumnIndex]; var indices = idToIndices.get(id); if (indices !== undefined) { var nIndices = indices.length; for (var j = 0; j < nheaders; j++) { var token = line[columnIndices[j]]; var v = vectors[j]; for (var r = 0; r < nIndices; r++) { v.setValue(indices[r], token); } } } } } for (var i = 0; i < vectors.length; i++) { morpheus.VectorUtil.maybeConvertStringToNumber(vectors[i]); } return vectors; }, // prompt for metadata field name in dataset and in file prompt : function(lines, dataset, controller, isColumns, sets) { var promptTool = {}; var _this = this; var header = lines != null ? lines[0].split('\t') : null; promptTool.execute = function(options) { var metadataName = options.input.dataset_field_name; var fileColumnName = options.input.file_field_name; var vectors = _this.annotate(lines, dataset, isColumns, sets, metadataName, fileColumnName); var render = []; for (var i = 0; i < vectors.length; i++) { render.push('text'); } controller.getProject().trigger('trackChanged', { vectors : vectors, render : render, columns : isColumns }); }; promptTool.toString = function() { return 'Select Fields To Match On'; }; promptTool.gui = function() { var items = [ { name : 'dataset_field_name', options : morpheus.MetadataUtil .getMetadataNames(isColumns ? dataset .getColumnMetadata() : dataset.getRowMetadata()), type : 'select', required : true } ]; if (lines) { items.push({ name : 'file_field_name', type : 'select', options : _.map(header, function(item) { return { name : item, value : item }; }), required : true }); } return items; }; morpheus.HeatMap.showTool(promptTool, controller); } };