From d1649c6e7aa631979c2ad5322cfe70f5e81f2403 Mon Sep 17 00:00:00 2001 From: logmosier Date: Mon, 19 Mar 2018 09:22:29 -0400 Subject: [PATCH 01/17] Landing box now uses gene validator to find uniprot ids --- src/client/features/search/index.js | 13 ++++++------- src/client/services/server-api/index.js | 2 +- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/src/client/features/search/index.js b/src/client/features/search/index.js index a983eefcf..d314ca619 100644 --- a/src/client/features/search/index.js +++ b/src/client/features/search/index.js @@ -63,12 +63,10 @@ class Search extends React.Component { getLandingResult() { const state = this.state; const query = { - q: state.query.q.trim(), - type: 'ProteinReference', - datasource: state.query.datasource, - species: '9606' + genes: state.query.q.trim(), + target: 'UNIPROTSWISSPROT', }; - if(query.q.includes(' ')){ + if(query.genes.includes(' ')){ this.setState({ landingLoading: false, landing:[] @@ -78,9 +76,10 @@ class Search extends React.Component { this.setState({ landingLoading: true },()=>{ - ServerAPI.findUniprotId(query).then(res=>{ + ServerAPI.geneQuery(query).then(res=>{ + res= res.geneInfo.map(gene=>gene.convertedAlias); if(!_.isEmpty(res)){ - ServerAPI.getProteinInformation(res[0]).then(result=>{ + ServerAPI.getProteinInformation(res).then(result=>{ this.setState({ landingLoading: false, landing:result, diff --git a/src/client/services/server-api/index.js b/src/client/services/server-api/index.js index 05ebc8b25..1ab2b0e7e 100644 --- a/src/client/services/server-api/index.js +++ b/src/client/services/server-api/index.js @@ -29,7 +29,7 @@ const ServerAPI = { }, geneQuery(query){ - return fetch(`/api/gene-query?${qs.stringify({genes: query})}`, defaultFetchOpts).then(res => res.json()); + return fetch(`/api/gene-query?${qs.stringify(query)}`, defaultFetchOpts).then(res => res.json()); }, findUniprotId(query){ From 70f237e13b5bcd6afa682f522e1180da81d8b538 Mon Sep 17 00:00:00 2001 From: logmosier Date: Mon, 19 Mar 2018 09:33:31 -0400 Subject: [PATCH 02/17] Removed uniprotIdSearch specific code --- src/client/services/server-api/index.js | 4 ---- src/server/pathway-commons/index.js | 1 - src/server/pathway-commons/search/index.js | 19 ------------------- src/server/routes/pc.js | 4 ---- 4 files changed, 28 deletions(-) diff --git a/src/client/services/server-api/index.js b/src/client/services/server-api/index.js index 1ab2b0e7e..ea6fc79d5 100644 --- a/src/client/services/server-api/index.js +++ b/src/client/services/server-api/index.js @@ -32,10 +32,6 @@ const ServerAPI = { return fetch(`/api/gene-query?${qs.stringify(query)}`, defaultFetchOpts).then(res => res.json()); }, - findUniprotId(query){ - return fetch(`/pc-client/uniprotIdSearch?${qs.stringify(query)}`, defaultFetchOpts).then(res => res.json()); - }, - getProteinInformation(uniprotId){ return fetch(`https://www.ebi.ac.uk/proteins/api/proteins?offset=0&size=1&accession=${uniprotId}`,defaultFetchOpts).then(res => res.json()); }, diff --git a/src/server/pathway-commons/index.js b/src/server/pathway-commons/index.js index 6c1428539..877894b8b 100644 --- a/src/server/pathway-commons/index.js +++ b/src/server/pathway-commons/index.js @@ -77,7 +77,6 @@ const PathwayCommonsService = { }; PathwayCommonsService.querySearch = _.memoize(search.querySearch, query => JSON.stringify(query)); -PathwayCommonsService.uniprotIdSearch = _.memoize(search.uniprotIdSearch, query => JSON.stringify(query)); PathwayCommonsService.datasources = _.memoize(datasources); // expose core cpath2 client api diff --git a/src/server/pathway-commons/search/index.js b/src/server/pathway-commons/search/index.js index 36384aecf..02f78abb7 100644 --- a/src/server/pathway-commons/search/index.js +++ b/src/server/pathway-commons/search/index.js @@ -74,23 +74,4 @@ const querySearch = async (query) => { return []; }; -const uniprotIdSearch = async (query) => { - const queries = await (processPhrase(sanitize(query.q.trim()))); - const filteredQueries = queries.filter(entry=>entry.includes('xrefid')); - if(!_.isEmpty(filteredQueries)){ - const searchResult = await search() - .query(query) //input query string - .q(filteredQueries) - .format('json') - .fetch(); - const searchSuccess = searchResult != null - if (searchSuccess && searchResult.searchHit.length > 0) { - const filteredResults = searchResult.searchHit.filter(hit => - hit.uri.startsWith('http://identifiers.org/uniprot/') - ); - return filteredResults.map(hit=>_.last(hit.uri.split('/'))); //Parses and returns the Uniprot id - } - } - return []; -}; module.exports = {querySearch:querySearch,uniprotIdSearch:uniprotIdSearch}; \ No newline at end of file diff --git a/src/server/routes/pc.js b/src/server/routes/pc.js index b233d1d6e..c64a58f6c 100644 --- a/src/server/routes/pc.js +++ b/src/server/routes/pc.js @@ -12,10 +12,6 @@ router.get('/querySearch', function (req, res) { pc.querySearch(req.query).then(r => res.json(r)); }); -router.get('/uniprotIdSearch',function (req, res) { - pc.uniprotIdSearch(req.query).then(r => res.json(r)); -}); - router.get('/:path', function (req, res) { res.redirect('http://www.pathwaycommons.org/pc2/' + req.params.path + '?' + qs.stringify(req.query)); }); From f277555f5312ba3e92e82bac50318aff1a24636a Mon Sep 17 00:00:00 2001 From: logmosier Date: Mon, 19 Mar 2018 09:37:43 -0400 Subject: [PATCH 03/17] missed one --- src/server/pathway-commons/search/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/server/pathway-commons/search/index.js b/src/server/pathway-commons/search/index.js index 02f78abb7..5d8242659 100644 --- a/src/server/pathway-commons/search/index.js +++ b/src/server/pathway-commons/search/index.js @@ -74,4 +74,4 @@ const querySearch = async (query) => { return []; }; -module.exports = {querySearch:querySearch,uniprotIdSearch:uniprotIdSearch}; \ No newline at end of file +module.exports = {querySearch}; \ No newline at end of file From fbb7193bbd875608e0b89d7e16cc8a0661e65259 Mon Sep 17 00:00:00 2001 From: logmosier Date: Tue, 20 Mar 2018 10:24:11 -0400 Subject: [PATCH 04/17] Renamed res and result --- src/client/features/search/index.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/client/features/search/index.js b/src/client/features/search/index.js index d314ca619..e91d7973e 100644 --- a/src/client/features/search/index.js +++ b/src/client/features/search/index.js @@ -76,13 +76,13 @@ class Search extends React.Component { this.setState({ landingLoading: true },()=>{ - ServerAPI.geneQuery(query).then(res=>{ - res= res.geneInfo.map(gene=>gene.convertedAlias); - if(!_.isEmpty(res)){ - ServerAPI.getProteinInformation(res).then(result=>{ + ServerAPI.geneQuery(query).then(geneQueryResult=>{ + geneQueryResult= geneQueryResult.geneInfo.map(gene=>gene.convertedAlias); + if(!_.isEmpty(geneQueryResult)){ + ServerAPI.getProteinInformation(geneQueryResult).then(infoResult=>{ this.setState({ landingLoading: false, - landing:result, + landing:infoResult, landingShowMore: [false,false], }); }); From 948be55b537b1a8cadc62907cce1406e7fea0c4e Mon Sep 17 00:00:00 2001 From: wxli0 Date: Wed, 21 Mar 2018 15:25:18 -0400 Subject: [PATCH 05/17] expose selected parameters for enrichment service, changed parameter from camelcase to snakecase relates to #541 --- src/server/routes/rest.js | 42 +++++++++++---------------------------- 1 file changed, 12 insertions(+), 30 deletions(-) diff --git a/src/server/routes/rest.js b/src/server/routes/rest.js index 37ee27367..952524673 100644 --- a/src/server/routes/rest.js +++ b/src/server/routes/rest.js @@ -88,22 +88,13 @@ router.get('/gene-query', (req, res) => { router.get('/enrichment', (req, res) => { const genes = req.query.genes; const tmpOptions = {}; - tmpOptions.output = req.query.output; - tmpOptions.organism = req.query.organism; - tmpOptions.significant = req.query.significant; - tmpOptions.sortByStructure = req.query.sortByStructure; - tmpOptions.orderedQuery = req.query.orderedQuery; - tmpOptions.asRanges = req.query.asRanges; - tmpOptions.noIea = req.query.noIea; - tmpOptions.underrep = req.query.underrep; - tmpOptions.hierfiltering = req.query.hierfiltering; - tmpOptions.userThr = req.query.userThr; - tmpOptions.minSetSize = req.query.minSetSize; - tmpOptions.maxSetSize = req.query.maxSetSize; - tmpOptions.thresholdAlgo = req.query.thresholdAlgo; - tmpOptions.domainSizeType = req.query.domainSizeType; + tmpOptions.ordered_query = req.query.orderedQuery; + tmpOptions.user_thr = req.query.userThr; + tmpOptions.min_set_size = req.query.minSetSize; + tmpOptions.max_set_size = req.query.maxSetSize; + tmpOptions.threshold_algo = req.query.thresholdAlgo; tmpOptions.custbg = req.query.custbg; - tmpOptions.custbgCb = req.query.custbgCb; + tmpOptions.custbg_cb = req.query.custbgCb; const userOptions = {}; for (const key in tmpOptions) { @@ -123,22 +114,13 @@ router.get('/enrichment', (req, res) => { router.post('/enrichment', (req, res) => { const genes = req.body.genes; const tmpOptions = {}; - tmpOptions.output = req.body.output; - tmpOptions.organism = req.body.organism; - tmpOptions.significant = req.body.significant; - tmpOptions.sortByStructure = req.body.sortByStructure; - tmpOptions.orderedQuery = req.body.orderedQuery; - tmpOptions.asRanges = req.body.asRanges; - tmpOptions.noIea = req.body.noIea; - tmpOptions.underrep = req.body.underrep; - tmpOptions.hierfiltering = req.body.hierfiltering; - tmpOptions.userThr = req.body.userThr; - tmpOptions.minSetSize = req.body.minSetSize; - tmpOptions.maxSetSize = req.body.maxSetSize; - tmpOptions.thresholdAlgo = req.body.thresholdAlgo; - tmpOptions.domainSizeType = req.body.domainSizeType; + tmpOptions.ordered_query = req.body.orderedQuery; + tmpOptions.user_thr = req.body.userThr; + tmpOptions.min_set_size = req.body.minSetSize; + tmpOptions.max_set_size = req.body.maxSetSize; + tmpOptions.threshold_algo = req.body.thresholdAlgo; tmpOptions.custbg = req.body.custbg; - tmpOptions.custbgCb = req.body.custbgCb; + tmpOptions.custbg_cb = req.body.custbgCb; const userOptions = {}; for (const key in tmpOptions) { From 43f3b2099b565b47b669b57c4fe1ab636c080b04 Mon Sep 17 00:00:00 2001 From: wxli0 Date: Fri, 23 Mar 2018 09:05:08 -0400 Subject: [PATCH 06/17] remove custbgCb --- src/server/routes/rest.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/server/routes/rest.js b/src/server/routes/rest.js index 952524673..7c7954454 100644 --- a/src/server/routes/rest.js +++ b/src/server/routes/rest.js @@ -94,7 +94,6 @@ router.get('/enrichment', (req, res) => { tmpOptions.max_set_size = req.query.maxSetSize; tmpOptions.threshold_algo = req.query.thresholdAlgo; tmpOptions.custbg = req.query.custbg; - tmpOptions.custbg_cb = req.query.custbgCb; const userOptions = {}; for (const key in tmpOptions) { @@ -120,7 +119,6 @@ router.post('/enrichment', (req, res) => { tmpOptions.max_set_size = req.body.maxSetSize; tmpOptions.threshold_algo = req.body.thresholdAlgo; tmpOptions.custbg = req.body.custbg; - tmpOptions.custbg_cb = req.body.custbgCb; const userOptions = {}; for (const key in tmpOptions) { From b439d6cb9b429c7550c7db52beca755cb3412d90 Mon Sep 17 00:00:00 2001 From: logmosier Date: Mon, 26 Mar 2018 17:04:52 -0400 Subject: [PATCH 07/17] Changes from issue #566 made --- src/client/common/config.js | 1 - .../common/cy/tooltips/format-content.js | 27 +++++++++++-------- src/client/common/cy/tooltips/index.js | 2 +- src/client/features/view/index.js | 8 ++++-- 4 files changed, 23 insertions(+), 15 deletions(-) diff --git a/src/client/common/config.js b/src/client/common/config.js index 57f82fe15..fdb492f0e 100644 --- a/src/client/common/config.js +++ b/src/client/common/config.js @@ -21,7 +21,6 @@ const databases = [ ['3DMET', 'http://identifiers.org/3dmet/', ''], ['Chemical Component Dictionary', 'http://identifiers.org/pdb-ccd/', ''], ['CAS', 'http://identifiers.org/cas/', ''], - ['Pathway Commons','/view?uri=http://pathwaycommons.org/pc2/',''], ['HPRD',' http://identifiers.org/hprd/',''], ['RefSeq',' http://identifiers.org/refseq/',''] ]; diff --git a/src/client/common/cy/tooltips/format-content.js b/src/client/common/cy/tooltips/format-content.js index b73092614..57d764b04 100644 --- a/src/client/common/cy/tooltips/format-content.js +++ b/src/client/common/cy/tooltips/format-content.js @@ -2,6 +2,7 @@ const h = require('hyperscript'); const classNames = require('classnames'); const _ = require('lodash'); const config = require('../../config'); +const queryString = require('query-string'); //Handle standard name related metadata fields const standardNameHandler = (pair) => makeTooltipItem(pair[1], 'Name: '); @@ -41,17 +42,17 @@ const databaseHandler = (pair, expansionFunction) => { }; //Handle interaction/Detailed views related fields -const interactionHandlerTrim =(pair, expansionFunction) => { +const interactionHandlerTrim =(pair, expansionFunction, title) => { let maxViews=8; const expansionLink = pair[1].length>maxViews? h('div.more-link', { onclick: () => expansionFunction(pair[0]) }, 'more »'):''; if (pair[1].length < 1) { return h('div.error'); } - return generateDetailedViewList(sortByDatabaseId(pair[1]), pair[1].length>maxViews, expansionLink,maxViews); + return generateDetailedViewList(sortByDatabaseId(pair[1]), pair[1].length>maxViews, expansionLink,maxViews,title); }; -const interactionHandler =(pair, expansionFunction) => { +const interactionHandler =(pair, expansionFunction, title) => { let maxViews=8; const expansionLink = pair[1].length>maxViews? h('div.more-link', { onclick: () => expansionFunction(pair[0]) }, '« less'):''; if (pair[1].length < 1) { return h('div.error'); } - return generateDetailedViewList(sortByDatabaseId(pair[1]),false, expansionLink,maxViews); + return generateDetailedViewList(sortByDatabaseId(pair[1]),false, expansionLink,maxViews,title); }; //Handle publication related fields @@ -103,7 +104,7 @@ const metaDataKeyMap = new Map() * Sample Input : parseMetadata(['Standard Name', 'TP53']) * Sample Output :
*/ -function parseMetadata(pair, trim = true, expansionFunction) { +function parseMetadata(pair, trim = true, expansionFunction, title) { const doNotRender = ['Data Source', 'Data SourceTrim', 'Display Name']; let key = pair[0]; @@ -114,7 +115,7 @@ function parseMetadata(pair, trim = true, expansionFunction) { let handler = metaDataKeyMap.get(key); if (handler) { - return handler(pair, expansionFunction); + return handler(pair, expansionFunction, title); } else if (!(trim) && !doNotRender.includes(key)) { return defaultHandler(pair); @@ -294,7 +295,7 @@ function generateIdList(dbIdObject, trim) { * Sample Input : generateDBLink('Reactome', 'R-HSA-59544', true) * Sample Output : */ -function generateDBLink(dbName, dbId, isDbVisible, otherName) { +function generateDBLink(dbName, dbId, isDbVisible) { //Get base url for dbid let db = config.databases; let className = ''; @@ -307,7 +308,7 @@ function generateDBLink(dbName, dbId, isDbVisible, otherName) { if (isDbVisible) { className = '-single-ref'; } - let label = otherName ? otherName :(isDbVisible ? dbName :dbId); + let label = isDbVisible ? dbName :dbId; //Build reference url if (link.length === 1 && link[0][1]) { @@ -433,12 +434,16 @@ function generateDatabaseList(sortedArray, trim, expansionLink) { return formatRenderValue(sortedArray,renderValue,expansionLink,trim,true,'Links'); } -function generateDetailedViewList(sortedArray, trim, expansionLink,maxViews) { - let name = sortedArray[0].database; +function generateDetailedViewList(sortedArray, trim, expansionLink,maxViews,title) { let list = sortedArray[0].ids; if(trim){list=list.slice(0,maxViews);} //Generate list - let renderValue = list.map((data,index) => [generateDBLink(name, data, true,'Interaction '+(index+1))],this); + let renderValue = list.map((data,index) => [h('div.fake-spacer', + h('a.db-link' , { href:'/view?', + search: queryString.stringify({uri:'http://pathwaycommons.org/pc2/'+data, + title:title, removeMenu:true }), target: '_blank' }, + 'Interaction '+(index+1)))]) + ; return formatRenderValue(sortedArray,renderValue,expansionLink,trim,false,'Detailed Views'); } diff --git a/src/client/common/cy/tooltips/index.js b/src/client/common/cy/tooltips/index.js index 9939fd102..d0b591ff3 100644 --- a/src/client/common/cy/tooltips/index.js +++ b/src/client/common/cy/tooltips/index.js @@ -89,7 +89,7 @@ class MetadataTip { if (!(this.data)) { this.data = []; } return h('div.tooltip-image', [ h('div.tooltip-heading', this.name), - h('div.tooltip-internal', h('div', (data).map(item => formatContent.parseMetadata(item, true, expandFunction)), this)) + h('div.tooltip-internal', h('div', (data).map(item => formatContent.parseMetadata(item, true, expandFunction, this.name)), this)) ]); } diff --git a/src/client/features/view/index.js b/src/client/features/view/index.js index 3dd242aa8..52c5e42ff 100644 --- a/src/client/features/view/index.js +++ b/src/client/features/view/index.js @@ -32,15 +32,19 @@ class View extends React.Component { ServerAPI.getGraphAndLayout(query.uri, 'latest').then(networkJSON => { const layoutConfig = getLayoutConfig(networkJSON.layout); - const componentConfig = _.merge({}, BaseNetworkView.config, { useSearchBar: true}); + if(query.removeMenu){ + BaseNetworkView.config.toolbarButtons.splice( + _.findIndex(BaseNetworkView.config.toolbarButtons, entry=>entry.id==='showInfo'),1); + } + const componentConfig = _.merge({},BaseNetworkView.config, { useSearchBar: true}); this.setState({ componentConfig: componentConfig, layoutConfig: layoutConfig, networkJSON: networkJSON.graph, networkMetadata: { uri: query.uri, - name: _.get(networkJSON, 'graph.pathwayMetadata.title.0', 'Unknown Network'), + name: query.title || _.get(networkJSON, 'graph.pathwayMetadata.title.0', 'Unknown Network'), datasource: _.get(networkJSON, 'graph.pathwayMetadata.dataSource.0', 'Unknown Data Source'), comments: networkJSON.graph.pathwayMetadata.comments, organism: networkJSON.graph.pathwayMetadata.organism From 3ae9e955e5c377141dba1ddfd1258fb638db41fe Mon Sep 17 00:00:00 2001 From: logmosier Date: Tue, 27 Mar 2018 11:38:29 -0400 Subject: [PATCH 08/17] Formating clean up + bug with expanded tooltips not sending title fix. --- .../common/cy/tooltips/format-content.js | 21 ++++++++++--------- src/client/common/cy/tooltips/index.js | 2 +- src/client/features/view/index.js | 3 ++- 3 files changed, 14 insertions(+), 12 deletions(-) diff --git a/src/client/common/cy/tooltips/format-content.js b/src/client/common/cy/tooltips/format-content.js index 57d764b04..32b54297b 100644 --- a/src/client/common/cy/tooltips/format-content.js +++ b/src/client/common/cy/tooltips/format-content.js @@ -431,21 +431,22 @@ function generateDatabaseList(sortedArray, trim, expansionLink) { //Generate list let renderValue = sortedArray.map(item => [generateIdList(item, trim)], this); - return formatRenderValue(sortedArray,renderValue,expansionLink,trim,true,'Links'); + return formatRenderValue(sortedArray, renderValue, expansionLink, trim, true, 'Links'); } -function generateDetailedViewList(sortedArray, trim, expansionLink,maxViews,title) { +function generateDetailedViewList(sortedArray, trim, expansionLink, maxViews, title) { let list = sortedArray[0].ids; if(trim){list=list.slice(0,maxViews);} //Generate list - let renderValue = list.map((data,index) => [h('div.fake-spacer', - h('a.db-link' , { href:'/view?', - search: queryString.stringify({uri:'http://pathwaycommons.org/pc2/'+data, - title:title, removeMenu:true }), target: '_blank' }, - 'Interaction '+(index+1)))]) - ; - - return formatRenderValue(sortedArray,renderValue,expansionLink,trim,false,'Detailed Views'); + let renderValue = list.map((data,index) => [h('div.fake-spacer', + h('a.db-link' ,{ + href:'/view?', + search: queryString.stringify({uri:'http://pathwaycommons.org/pc2/'+data, title:title, removeMenu:true}), + target: '_blank', + }, 'Interaction '+(index+1)) + )]); + + return formatRenderValue(sortedArray, renderValue, expansionLink, trim, false, 'Detailed Views'); } function formatRenderValue(sortedArray, renderValue, expansionLink, trim, list,name){ diff --git a/src/client/common/cy/tooltips/index.js b/src/client/common/cy/tooltips/index.js index d0b591ff3..462853852 100644 --- a/src/client/common/cy/tooltips/index.js +++ b/src/client/common/cy/tooltips/index.js @@ -116,7 +116,7 @@ class MetadataTip { if (!(this.data)) { this.data = []; } return h('div.tooltip-image', [ h('div.tooltip-heading', this.name), - h('div.tooltip-internal', h('div', (data).map(item => formatContent.parseMetadata(item, !this.isExpanded(item[0]), getExpansionFunction(item)), this))) + h('div.tooltip-internal', h('div', (data).map(item => formatContent.parseMetadata(item, !this.isExpanded(item[0]), getExpansionFunction(item), this.name), this))) ] ); } diff --git a/src/client/features/view/index.js b/src/client/features/view/index.js index 52c5e42ff..fb509a8d2 100644 --- a/src/client/features/view/index.js +++ b/src/client/features/view/index.js @@ -34,7 +34,8 @@ class View extends React.Component { const layoutConfig = getLayoutConfig(networkJSON.layout); if(query.removeMenu){ BaseNetworkView.config.toolbarButtons.splice( - _.findIndex(BaseNetworkView.config.toolbarButtons, entry=>entry.id==='showInfo'),1); + _.findIndex(BaseNetworkView.config.toolbarButtons, entry=>entry.id==='showInfo'),1 + ); } const componentConfig = _.merge({},BaseNetworkView.config, { useSearchBar: true}); From 67da6f2eee2f5ae8d262e5360900e1b0363bd013 Mon Sep 17 00:00:00 2001 From: logmosier Date: Tue, 27 Mar 2018 11:44:58 -0400 Subject: [PATCH 09/17] Variable name change --- src/client/common/cy/tooltips/format-content.js | 2 +- src/client/features/view/index.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/client/common/cy/tooltips/format-content.js b/src/client/common/cy/tooltips/format-content.js index 32b54297b..04c3c22a0 100644 --- a/src/client/common/cy/tooltips/format-content.js +++ b/src/client/common/cy/tooltips/format-content.js @@ -441,7 +441,7 @@ function generateDetailedViewList(sortedArray, trim, expansionLink, maxViews, ti let renderValue = list.map((data,index) => [h('div.fake-spacer', h('a.db-link' ,{ href:'/view?', - search: queryString.stringify({uri:'http://pathwaycommons.org/pc2/'+data, title:title, removeMenu:true}), + search: queryString.stringify({uri:'http://pathwaycommons.org/pc2/'+data, title:title, removeInfoMenu:true}), target: '_blank', }, 'Interaction '+(index+1)) )]); diff --git a/src/client/features/view/index.js b/src/client/features/view/index.js index fb509a8d2..20bbebaae 100644 --- a/src/client/features/view/index.js +++ b/src/client/features/view/index.js @@ -32,7 +32,7 @@ class View extends React.Component { ServerAPI.getGraphAndLayout(query.uri, 'latest').then(networkJSON => { const layoutConfig = getLayoutConfig(networkJSON.layout); - if(query.removeMenu){ + if(query.removeInfoMenu){ BaseNetworkView.config.toolbarButtons.splice( _.findIndex(BaseNetworkView.config.toolbarButtons, entry=>entry.id==='showInfo'),1 ); From bb01dded1964ccc7d6255316635339f945474ac6 Mon Sep 17 00:00:00 2001 From: logmosier Date: Thu, 29 Mar 2018 14:03:42 -0400 Subject: [PATCH 10/17] Changed target to UNIPROT --- src/client/features/search/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/client/features/search/index.js b/src/client/features/search/index.js index e91d7973e..c20bfc7e3 100644 --- a/src/client/features/search/index.js +++ b/src/client/features/search/index.js @@ -64,7 +64,7 @@ class Search extends React.Component { const state = this.state; const query = { genes: state.query.q.trim(), - target: 'UNIPROTSWISSPROT', + target: 'UNIPROT', }; if(query.genes.includes(' ')){ this.setState({ From 152a6d6099a5e3276a64190719088376f544dbfc Mon Sep 17 00:00:00 2001 From: wxli0 Date: Mon, 2 Apr 2018 10:08:42 -0400 Subject: [PATCH 11/17] fixed a bug in gene-validator output option sent status 400 when error relates to #591 --- src/server/enrichment-map/gene-validator/index.js | 9 +++++++-- src/server/enrichment-map/gene-validator/validityInfo.js | 2 +- src/server/routes/rest.js | 2 +- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/server/enrichment-map/gene-validator/index.js b/src/server/enrichment-map/gene-validator/index.js index 519fcdc9a..789b63006 100644 --- a/src/server/enrichment-map/gene-validator/index.js +++ b/src/server/enrichment-map/gene-validator/index.js @@ -39,8 +39,13 @@ const convertGConvertNames = (gConvertName) => { const validatorGconvert = (query, userOptions) => { const promise = new Promise((resolve, reject) => { const formData = _.assign({}, defaultOptions, userOptions, { query: query }); + console.log(formData); formData.organism = formData.organism.toLowerCase(); - formData.target = convertGConvertNames(formData.target.toUpperCase()); + const initialTarget = formData.target.toUpperCase(); + console.log(initialTarget) + console.log(convertGConvertNames); + console.log(convertGConvertNames(initialTarget)); + formData.target = convertGConvertNames(initialTarget); const invalidInfo = {invalidTarget: '', invalidOrganism: ''}; if (!validOrganism.includes(formData.organism)) { invalidInfo.invalidOrganism = formData.organism; @@ -79,7 +84,7 @@ const validatorGconvert = (query, userOptions) => { } }); - const ret = { options: {target: formData.target, organism: formData.organism}, unrecognized: unrecognized, duplicate: duplicate, geneInfo: geneInfo }; + const ret = { options: {target: initialTarget, organism: formData.organism}, unrecognized: unrecognized, duplicate: duplicate, geneInfo: geneInfo }; resolve(ret); }); }); diff --git a/src/server/enrichment-map/gene-validator/validityInfo.js b/src/server/enrichment-map/gene-validator/validityInfo.js index 1e3af0ecb..9bfa2e93d 100644 --- a/src/server/enrichment-map/gene-validator/validityInfo.js +++ b/src/server/enrichment-map/gene-validator/validityInfo.js @@ -253,6 +253,6 @@ const validOrganism = ['aaegypti', 'vvinifera', 'zmays']; -const validTarget = ['ENSG', 'HGNC', 'HGNC_ACC', 'UNIPROTSWISSPROT', 'ENTREZGENE', 'ENTREZGENE_ACC']; +const validTarget = ['ENSG', 'HGNC', 'HGNC_ACC', 'UNIPROTSWISSPROT', 'ENTREZGENE_ACC']; module.exports = {validOrganism, validTarget}; \ No newline at end of file diff --git a/src/server/routes/rest.js b/src/server/routes/rest.js index 56cc89c23..2c353b88e 100644 --- a/src/server/routes/rest.js +++ b/src/server/routes/rest.js @@ -80,7 +80,7 @@ router.get('/gene-query', (req, res) => { validatorGconvert(genes, userOptions).then(gconvertResult => { res.json(gconvertResult); }).catch((invalidInfoError) => { - res.json({invalidTarget: invalidInfoError.invalidTarget, invalidOrganism: invalidInfoError.invalidOrganism}); + res.status(400).send({invalidTarget: invalidInfoError.invalidTarget, invalidOrganism: invalidInfoError.invalidOrganism}); }); }); From 24ac0b3479c7e493dd04e2d028b48d91f0488486 Mon Sep 17 00:00:00 2001 From: wxli0 Date: Mon, 2 Apr 2018 10:10:38 -0400 Subject: [PATCH 12/17] remove comments --- src/server/enrichment-map/gene-validator/index.js | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/server/enrichment-map/gene-validator/index.js b/src/server/enrichment-map/gene-validator/index.js index 789b63006..69bb58fc0 100644 --- a/src/server/enrichment-map/gene-validator/index.js +++ b/src/server/enrichment-map/gene-validator/index.js @@ -39,12 +39,8 @@ const convertGConvertNames = (gConvertName) => { const validatorGconvert = (query, userOptions) => { const promise = new Promise((resolve, reject) => { const formData = _.assign({}, defaultOptions, userOptions, { query: query }); - console.log(formData); formData.organism = formData.organism.toLowerCase(); const initialTarget = formData.target.toUpperCase(); - console.log(initialTarget) - console.log(convertGConvertNames); - console.log(convertGConvertNames(initialTarget)); formData.target = convertGConvertNames(initialTarget); const invalidInfo = {invalidTarget: '', invalidOrganism: ''}; if (!validOrganism.includes(formData.organism)) { From 2a3fed7f11ba914afc5b6ba31ac3432dddb1634f Mon Sep 17 00:00:00 2001 From: logmosier Date: Mon, 2 Apr 2018 10:48:08 -0400 Subject: [PATCH 13/17] Fixed the case where the colour tab would disappear. --- src/client/features/interactions/filter-menu.js | 2 +- .../features/view/sidebarMenus/interactionFilterMenu.css | 9 ++++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/client/features/interactions/filter-menu.js b/src/client/features/interactions/filter-menu.js index a01d1e36d..6e4a419bc 100644 --- a/src/client/features/interactions/filter-menu.js +++ b/src/client/features/interactions/filter-menu.js @@ -15,7 +15,7 @@ class InteractionsFilterMenu extends React.Component { [ h('div',{className:classNames(type,'interaction-filter-legend')}), h('h3.button-label',type), - h('i', {className: classNames('common-icon-button','material-icons',{ 'common-icon-button-active': !clicked})}, clicked ? 'close':'check') + h('i', {className: classNames('common-icon-button','material-icons','icon-cutoff',{ 'common-icon-button-active': !clicked})}, clicked ? 'close':'check') ] )); return h('div',[ diff --git a/src/styles/features/view/sidebarMenus/interactionFilterMenu.css b/src/styles/features/view/sidebarMenus/interactionFilterMenu.css index 69775c437..09e716224 100644 --- a/src/styles/features/view/sidebarMenus/interactionFilterMenu.css +++ b/src/styles/features/view/sidebarMenus/interactionFilterMenu.css @@ -8,7 +8,6 @@ display: flex; justify-content: flex-start; cursor: pointer; - border-style: solid; border-color: var(--light-base-colour-dark); border-width: 1px 1px 0px 1px; @@ -39,14 +38,22 @@ padding-left: 2px; display: inline-flex; margin: 0px auto 0px 0px; + word-break:break-all; } .interaction-filter-legend{ height:50px; width: 30px; + flex-shrink: 0; display: inline-flex; } +@media screen and (max-width: 1010px) { + .icon-cutoff { + display:none; + } +} + .Binding{ background-color:green; } From c3b5380b0448e82484c1d04fccebbdd4f657ae13 Mon Sep 17 00:00:00 2001 From: wxli0 Date: Mon, 2 Apr 2018 11:00:33 -0400 Subject: [PATCH 14/17] add error status to post --- src/server/routes/rest.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/server/routes/rest.js b/src/server/routes/rest.js index 2c353b88e..9fb4b0abd 100644 --- a/src/server/routes/rest.js +++ b/src/server/routes/rest.js @@ -100,6 +100,8 @@ router.post('/gene-query', (req, res) => { validatorGconvert(genes, userOptions).then(gconvertResult => { res.json(gconvertResult); + }).catch((invalidInfoError) => { + res.status(400).send({invalidTarget: invalidInfoError.invalidTarget, invalidOrganism: invalidInfoError.invalidOrganism}); }); }); From 9e797cc51770044b9bcc9f586671805ec50fb0e2 Mon Sep 17 00:00:00 2001 From: wxli0 Date: Mon, 2 Apr 2018 14:27:29 -0400 Subject: [PATCH 15/17] added error cases in enrichment service relates to #594 --- .../enrichment-map/enrichment/enrichment.js | 18 ++++++++++++------ src/server/routes/rest.js | 4 ++++ 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/src/server/enrichment-map/enrichment/enrichment.js b/src/server/enrichment-map/enrichment/enrichment.js index d91df05b1..4f6327830 100644 --- a/src/server/enrichment-map/enrichment/enrichment.js +++ b/src/server/enrichment-map/enrichment/enrichment.js @@ -57,22 +57,28 @@ const enrichment = (query, userSetting) => { const thresholdAlgoVal = formData.threshold_algo; const custbgCbVal = Number(formData.custbg_cb); if (orderedQueryVal != 0 && orderedQueryVal != 1) { - throw new Error('ERROR: orderedQuery should be 1 or 0'); + reject(new Error('ERROR: orderedQuery should be 1 or 0')); } if (isNaN(userThrVal) || userThrVal > 1 || userThrVal < 0) { - throw new Error('ERROR: userThrVal should be a number [0, 1]') + reject(new Error('ERROR: userThrVal should be a number [0, 1]')); } if (isNaN(minSetSizeVal)) { - throw new Error('ERROR: minSetSize should be a number') + reject(new Error('ERROR: minSetSize should be a number')); + } + if (minSetSizeVal < 0) { + reject(new Error('ERROR: minSetSize should be >= 0')); } if (isNaN(maxSetSizeVal)) { - throw new Error('ERROR: maxSetSize should be a number'); + reject(new Error('ERROR: maxSetSize should be a number')); + } + if (maxSetSizeVal < minSetSizeVal) { + reject(new Error('ERROR: maxSetSize should be >= minSetSize')); } if (thresholdAlgoVal != 'analytical' && thresholdAlgoVal != 'bonferroni' && thresholdAlgoVal != 'fdr') { - throw new Error('ERROR: thresholdAlgoVal should be one of analytical, bonferroni, fdr'); + reject(new Error('ERROR: thresholdAlgoVal should be one of analytical, bonferroni, fdr')); } if (custbgCbVal != 0 && custbgCbVal != 1) { - throw new Error('ERROR: custbgCb should be 1 or 0') + reject(new Error('ERROR: custbgCb should be 1 or 0')); } request.post({ url: gProfilerURL, formData: formData }, (err, httpResponse, gProfilerResponse) => { diff --git a/src/server/routes/rest.js b/src/server/routes/rest.js index d2fa703ea..c5d5e0d68 100644 --- a/src/server/routes/rest.js +++ b/src/server/routes/rest.js @@ -128,6 +128,8 @@ router.get('/enrichment', (req, res) => { enrichment(genes, userOptions).then(enrichmentResult => { res.json(enrichmentResult); + }).catch((err) => { + res.status(400).send(err.message); }); }); @@ -153,6 +155,8 @@ router.post('/enrichment', (req, res) => { enrichment(genes, userOptions).then(enrichmentResult => { res.json(enrichmentResult); + }).catch((err) => { + res.status(400).send(err.message); }); }); From deec050daad9ec141da1c834b2a7b65833a86582 Mon Sep 17 00:00:00 2001 From: wxli0 Date: Mon, 2 Apr 2018 15:32:35 -0400 Subject: [PATCH 16/17] expose weights and cutoff in emap service relates to #526 --- .../enrichment-map/emap/generateGraphInfo.js | 32 +++++++++++++++---- .../enrichment-map/emap/generateInfo.js | 4 +-- src/server/enrichment-map/emap/intersect.js | 8 ++--- src/server/routes/rest.js | 6 +++- 4 files changed, 36 insertions(+), 14 deletions(-) diff --git a/src/server/enrichment-map/emap/generateGraphInfo.js b/src/server/enrichment-map/emap/generateGraphInfo.js index ddf6f97ca..ce676d1dd 100644 --- a/src/server/enrichment-map/emap/generateGraphInfo.js +++ b/src/server/enrichment-map/emap/generateGraphInfo.js @@ -20,7 +20,30 @@ const _ = require('lodash'); // input ["GO:1902275", "GO:2001252", "GO:1905269", "GO:0051053"] // returns a cytoscape object -const generateGraphInfo = (pathwayIdList) => { +const generateGraphInfo = (pathwayIdList, cutoff = 0.375, JCWeight, OCWeight) => { + if (cutoff < 0 || cutoff > 1) { throw new Error('ERROR: cutoff out of range [0, 1]');} + if (isNaN(Number(cutoff))) { throw new Error('ERROR: cutoff is not a number'); } + + if (JCWeight < 0 || JCWeight > 1) { + throw new Error('ERROR: JCWeight out of range [0, 1]'); + } + if (OCWeight < 0 || OCWeight > 1) { + throw new Error('ERROR: OCWeight out of range [0, 1]'); + } + if (JCWeight != undefined && isNaN(Number(JCWeight))) {throw new Error('ERROR: JCWeight should be a number');} + if (OCWeight != undefined && isNaN(Number(OCWeight))) {throw new Error('ERROR: OCWeight should be a number');} + if (OCWeight != undefined && JCWeight != undefined && Number(OCWeight) + Number(JCWeight) != 1) { + throw new Error('ERROR: OCWeight + JCWeight should be 1'); + } + if (JCWeight === undefined && OCWeight === undefined) { + JCWeight = 0.5; + OCWeight = 0.5; + } else if (JCWeight === undefined) { + JCWeight = 1 - OCWeight; + } else if (OCWeight === undefined) { + OCWeight = 1 - JCWeight; + } + // check unrecognized and duplicates, modify pathwayIdList const unrecognized = []; for (let i = 0; i < pathwayIdList.length; ++i) { @@ -48,7 +71,7 @@ const generateGraphInfo = (pathwayIdList) => { _.forEach(nodeInfo, node => { elements.push({ data: { id: node.pathwayId } }); }); - const edgeInfo = generateEdgeInfo(pathwayIdList); + const edgeInfo = generateEdgeInfo(pathwayIdList, JCWeight, cutoff); _.forEach(edgeInfo, edge => { const sourceIndex = 0; const targetIndex = 1; @@ -71,8 +94,3 @@ const generateGraphInfo = (pathwayIdList) => { module.exports = { generateGraphInfo }; - -//simple testing -//console.log(generateGraphInfo(["GO:1902275", "GO:2001252", "GO:1905269"])); -// const result = generateGraphInfo(["GO:1902275", "GO:2001252", "GO:1905269"]); -// console.log(JSON.stringify(result)); \ No newline at end of file diff --git a/src/server/enrichment-map/emap/generateInfo.js b/src/server/enrichment-map/emap/generateInfo.js index ba1de4626..2bce59c48 100644 --- a/src/server/enrichment-map/emap/generateInfo.js +++ b/src/server/enrichment-map/emap/generateInfo.js @@ -20,8 +20,8 @@ const fetchPathwayInfo = (pathwayList) => { // {edgeId: "GO:1902275_GO:0051053", intersection: [gene1], similarity: 0.1}, // {edgeId: "GO:2001252_GO:0051053", intersection: [gene1], similarity: 0.1}] // cutoff = 0.375 unless specified -const generateEdgeInfo = (pathwayIdList, cutoff = 0.375) => { - return filterEdges(pathwayListGraph(fetchPathwayInfo(pathwayIdList)), cutoff); +const generateEdgeInfo = (pathwayIdList, JCWeight, cutoff = 0.375) => { + return filterEdges(pathwayListGraph(fetchPathwayInfo(pathwayIdList), JCWeight), cutoff); }; diff --git a/src/server/enrichment-map/emap/intersect.js b/src/server/enrichment-map/emap/intersect.js index 1737d8480..96c3e563a 100644 --- a/src/server/enrichment-map/emap/intersect.js +++ b/src/server/enrichment-map/emap/intersect.js @@ -8,7 +8,7 @@ const _ = require('lodash'); // JC/OC calculation // output: JSON object // {edgeId: pathwayxyz_pathwayabc, intersection: [gene1, gene3], similarity: 0.6} -const pathwayPairGraph = (pathway1, pathway2) => { +const pathwayPairGraph = (pathway1, pathway2, JCWeight) => { let intersectionCount = 0; const intersection = []; _.forEach(pathway1.genes, gene => { @@ -18,7 +18,7 @@ const pathwayPairGraph = (pathway1, pathway2) => { } }); // JC/OC calculation - const similarity = 0.5*(intersectionCount/(pathway1.genes.length+pathway2.genes.length-intersectionCount))+0.5*(intersectionCount/Math.min(pathway1.genes.length, pathway2.genes.length)); + const similarity = JCWeight*(intersectionCount/(pathway1.genes.length+pathway2.genes.length-intersectionCount))+(1-JCWeight)*(intersectionCount/Math.min(pathway1.genes.length, pathway2.genes.length)); return {edgeId: pathway1.pathwayId+'_'+pathway2.pathwayId, intersection: intersection, similarity: similarity}; }; @@ -35,11 +35,11 @@ const pathwayPairGraph = (pathway1, pathway2) => { // {edgeId: "pathway2_pathway3", intersection: [], similarity: 0.1}, // {edgeId: "pathway2_pathway4", intersection: [], similarity: 0.1}, // {edgeId: "pathway3_pathway4", intersection: [gene1], similarity: 0.1}] -const pathwayListGraph = (pathwayList) => { +const pathwayListGraph = (pathwayList, JCWeight) => { const ret = []; for (let i = 0; i < pathwayList.length; ++i) { for (let j = i + 1; j < pathwayList.length; ++j) { - ret.push(pathwayPairGraph(pathwayList[i], pathwayList[j])); + ret.push(pathwayPairGraph(pathwayList[i], pathwayList[j], JCWeight)); } } return ret; diff --git a/src/server/routes/rest.js b/src/server/routes/rest.js index d2fa703ea..054ec573d 100644 --- a/src/server/routes/rest.js +++ b/src/server/routes/rest.js @@ -171,7 +171,11 @@ router.post('/emap', (req, res) => { const cutoff = req.body.cutoff; const JCWeight = req.body.JCWeight; const OCWeight = req.body.OCWeight; - res.json(generateGraphInfo(pathwayIdList, cutoff, JCWeight, OCWeight)); + try { + res.json(generateGraphInfo(pathwayIdList, cutoff, JCWeight, OCWeight)); + } catch (err) { + res.status(400).send(err.message); + } }); // Expose a rest endpoint for controller.endSession From 3e52875707252cfbc69c9dea7c99621244d3fe0d Mon Sep 17 00:00:00 2001 From: wxli0 Date: Tue, 3 Apr 2018 09:26:04 -0400 Subject: [PATCH 17/17] remove custbgCb relates to #603 --- src/server/enrichment-map/enrichment/enrichment.js | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/server/enrichment-map/enrichment/enrichment.js b/src/server/enrichment-map/enrichment/enrichment.js index 4f6327830..26a4c6dfc 100644 --- a/src/server/enrichment-map/enrichment/enrichment.js +++ b/src/server/enrichment-map/enrichment/enrichment.js @@ -40,7 +40,6 @@ const defaultSetting = { "threshold_algo": "fdr", "domain_size_type": "annotated", "custbg": [], - "custbg_cb": 0, "sf_GO:BP": 1, "sf_REAC": 1, }; @@ -55,7 +54,6 @@ const enrichment = (query, userSetting) => { const minSetSizeVal = Number(formData.min_set_size); const maxSetSizeVal = Number(formData.max_set_size); const thresholdAlgoVal = formData.threshold_algo; - const custbgCbVal = Number(formData.custbg_cb); if (orderedQueryVal != 0 && orderedQueryVal != 1) { reject(new Error('ERROR: orderedQuery should be 1 or 0')); } @@ -77,9 +75,6 @@ const enrichment = (query, userSetting) => { if (thresholdAlgoVal != 'analytical' && thresholdAlgoVal != 'bonferroni' && thresholdAlgoVal != 'fdr') { reject(new Error('ERROR: thresholdAlgoVal should be one of analytical, bonferroni, fdr')); } - if (custbgCbVal != 0 && custbgCbVal != 1) { - reject(new Error('ERROR: custbgCb should be 1 or 0')); - } request.post({ url: gProfilerURL, formData: formData }, (err, httpResponse, gProfilerResponse) => { if (err) {