morpheus.SimilarityMatrixTool = function() { }; morpheus.SimilarityMatrixTool.Functions = [ morpheus.Euclidean, morpheus.Jaccard, morpheus.Cosine, morpheus.Pearson, morpheus.Spearman ]; morpheus.SimilarityMatrixTool.Functions.fromString = function(s) { for (var i = 0; i < morpheus.SimilarityMatrixTool.Functions.length; i++) { if (morpheus.SimilarityMatrixTool.Functions[i].toString() === s) { return morpheus.SimilarityMatrixTool.Functions[i]; } } throw new Error(s + ' not found'); }; morpheus.SimilarityMatrixTool.execute = function(dataset, input) { var isColumnMatrix = input.compute_matrix_for == 'Columns'; var f = morpheus.SimilarityMatrixTool.Functions.fromString(input.metric); return morpheus.HCluster.computeDistanceMatrix( isColumnMatrix ? new morpheus.TransposedDatasetView(dataset) : dataset, f); }; morpheus.SimilarityMatrixTool.prototype = { toString : function() { return 'Similarity Matrix'; }, init : function(project, form) { }, gui : function() { return [ { name : 'metric', options : morpheus.SimilarityMatrixTool.Functions, value : morpheus.SimilarityMatrixTool.Functions[3].toString(), type : 'select' }, { name : 'compute_matrix_for', options : [ 'Columns', 'Rows' ], value : 'Columns', type : 'radio' } ]; }, execute : function(options) { var project = options.project; var controller = options.controller; var isColumnMatrix = options.input.compute_matrix_for == 'Columns'; var f = morpheus.SimilarityMatrixTool.Functions .fromString(options.input.metric); var dataset = project.getSortedFilteredDataset(); var blob = new Blob( [ 'self.onmessage = function(e) {' + 'importScripts(e.data.scripts);' + 'self.postMessage(morpheus.SimilarityMatrixTool.execute(morpheus.Dataset.fromJson(e.data.dataset), e.data.input));' + '}' ]); var url = window.URL.createObjectURL(blob); var worker = new Worker(url); worker.postMessage({ scripts : morpheus.Util.getScriptPath(), dataset : morpheus.Dataset.toJson(dataset, { columnFields : [], rowFields : [] }), input : options.input }); worker.onmessage = function(e) { var name = controller.getName(); var matrix = e.data; var n = isColumnMatrix ? dataset.getColumnCount() : dataset .getRowCount(); var d = new morpheus.Dataset({ name : name, rows : n, columns : n }); // set the diagonal var isDistance = f.toString() === morpheus.Euclidean.toString() || f.toString() === morpheus.Jaccard.toString(); for (var i = 1; i < n; i++) { for (var j = 0; j < i; j++) { var value = matrix[i][j]; d.setValue(i, j, value); d.setValue(j, i, value); } } // no need to set diagonal if not distance as array already // initialized to 0 if (!isDistance) { for (var i = 0; i < n; i++) { d.setValue(i, i, 1); } } var metadata = isColumnMatrix ? dataset.getColumnMetadata() : dataset.getRowMetadata(); d.rowMetadataModel = morpheus.MetadataUtil.shallowCopy(metadata); d.columnMetadataModel = morpheus.MetadataUtil.shallowCopy(metadata); var colorScheme; if (!isDistance) { colorScheme = { type : 'fixed', map : [ { value : -1, color : 'blue' }, { value : 0, color : 'white' }, { value : 1, color : 'red' } ] }; } else { colorScheme = { type : 'fixed', map : [ { value : 0, color : 'white' }, { value : morpheus.DatasetUtil.max(d), color : 'red' } ] }; } new morpheus.HeatMap({ colorScheme : colorScheme, name : name, dataset : d, parent : controller, inheritFromParentOptions : { rows : !isColumnMatrix, columns : isColumnMatrix } }); worker.terminate(); window.URL.revokeObjectURL(url); }; return worker; } };