gramene-search 1.3.0 → 1.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gramene-search",
3
- "version": "1.3.0",
3
+ "version": "1.4.1",
4
4
  "description": "search wrapper for gramene",
5
5
  "source": "src/index.js",
6
6
  "main": "dist/index.js",
@@ -226,6 +226,24 @@ curatedGenes.reactCuratedGenes = createSelector(
226
226
  }
227
227
  );
228
228
 
229
+ const grameneGermplasm = createAsyncResourceBundle( {
230
+ name: 'grameneGermplasm',
231
+ actionBaseType: 'GRAMENE_GERMPLASM',
232
+ persist: true,
233
+ getPromise: ({store}) => {
234
+ return fetch(`${store.selectGrameneAPI()}/germplasm?rows=-1`)
235
+ .then(res => res.json())
236
+ .then(res => _.groupBy(res, 'ens_id'))
237
+ }
238
+ });
239
+ grameneGermplasm.reactGrameneGermplasm = createSelector(
240
+ 'selectGrameneGermplasmShouldUpdate',
241
+ (shouldUpdate) => {
242
+ if (shouldUpdate) {
243
+ return { actionCreator: 'doFetchGrameneGermplasm' }
244
+ }
245
+ }
246
+ );
229
247
  //
230
248
  // const grameneExpressionAssays = createAsyncResourceBundle( {
231
249
  // name: 'grameneExpressionAssays',
@@ -515,4 +533,4 @@ const grameneOrthologs = {
515
533
  // });
516
534
 
517
535
 
518
- export default [grameneSuggestions, grameneSearch, grameneMaps, grameneTaxonomy, grameneTaxDist, grameneOrthologs, curatedGenes, grameneGeneAttribs, expressionSamples, expressionStudies];
536
+ export default [grameneSuggestions, grameneSearch, grameneMaps, grameneTaxonomy, grameneTaxDist, grameneOrthologs, curatedGenes, grameneGermplasm, grameneGeneAttribs, expressionSamples, expressionStudies];
@@ -139,6 +139,12 @@ class Gene extends React.Component {
139
139
  super(props);
140
140
  this.state = {
141
141
  details: [
142
+ {
143
+ id: 'VEP',
144
+ label: 'Germplasm',
145
+ popup: 'Germplasm with protein truncating variants (PTVs)',
146
+ available: false
147
+ },
142
148
  {
143
149
  id: 'sequences',
144
150
  label: 'Sequences',
@@ -175,12 +181,6 @@ class Gene extends React.Component {
175
181
  popup: 'Curated Publications',
176
182
  available: false
177
183
  },
178
- // {
179
- // id: 'VEP',
180
- // label: 'Germplasm (PTV)',
181
- // popup: 'Germplasm with protein truncating variants',
182
- // available: false
183
- // },
184
184
  {
185
185
  id: 'xrefs',
186
186
  label: 'Xrefs',
@@ -0,0 +1,9 @@
1
+ .button-like-link {
2
+ display: inline-block;
3
+ padding: 0;
4
+ background-color: #fff0;
5
+ color: #007bff;
6
+ text-decoration: underline;
7
+ border: none;
8
+ cursor: pointer;
9
+ }
@@ -1,31 +1,98 @@
1
- import React, { useState, useEffect } from 'react';
1
+ import React, {useState, useEffect, useMemo} from 'react';
2
2
  import {connect} from "redux-bundler-react";
3
- import {Tabs, Tab, Form, Container, Row, Col, ToggleButton, ButtonGroup } from 'react-bootstrap';
4
- import * as console from "console";
3
+ import {Button} from 'react-bootstrap';
4
+ import { AgGridReact } from "ag-grid-react";
5
+ import "ag-grid-community/styles/ag-grid.css";
6
+ import "ag-grid-community/styles/ag-theme-quartz.css";
7
+ import "./VEP.css";
8
+ import {suggestionToFilters} from "../../utils";
5
9
 
10
+ const metaRenderer = params => {
11
+ if (params.value.field === "germplasm") { // link to grin or SorgMutDB
12
+ if (params.value.germplasm_dbid) {
13
+ return <a target="_blank" href={`https://npgsweb.ars-grin.gov/gringlobal/accessiondetail.aspx?id=${params.value.germplasm_dbid}`}>{params.value.pub_id}</a>;
14
+ }
15
+ return (
16
+ <form id={params.value.pub_id} action="https://www.depts.ttu.edu/igcast/sorbmutdb.php" method="post" target="_blank">
17
+ <input type="hidden" name="search" value={params.value.gene_id.replace('SORBI_3','Sobic.')} />
18
+ <input type="hidden" name="submit" value="Search" />
19
+ <button type="submit" className="button-like-link">SorbMutDB</button>
20
+ </form>
21
+ );
22
+ }
23
+ if (params.value.field === "search") { // search filter
24
+ const currentURL = new URL(window.location.href);
25
+ currentURL.search = '';
26
+ currentURL.searchParams.set('category', 'Germplasm');
27
+ currentURL.searchParams.set('fq_field',`VEP__merged__${study_info[params.value.pop_id].type}__attr_ss`);
28
+ currentURL.searchParams.set('fq_value',params.value.ens_id);
29
+ currentURL.searchParams.set('name', params.value.ens_id);
30
+
31
+ return <Button size='sm' href={currentURL.toString()}>Search</Button>
32
+ }
33
+ return params.value.label
34
+ }
35
+ const sortByLabel = (valueA, valueB, nodeA, nodeB, isDescending) => {
36
+ if (valueA.label === valueB.label) return 0;
37
+ return (valueA.label > valueB.label) ? 1 : -1;
38
+ }
6
39
 
40
+ const study_info = {
41
+ '1' : {label: 'Purdue EMS', type: 'EMS'},
42
+ '2' : {label: 'USDA Lubbock EMS', type: 'EMS'},
43
+ '3' : {label: 'Lozano', type: 'NAT'},
44
+ '4' : {label: 'USDA Lubbock EMS', type: 'EMS'},
45
+ '5' : {label: 'Boatwright SAP', type: 'NAT'}
46
+ };
7
47
  const Detail = props => {
8
48
  const gene = props.geneDocs[props.searchResult.id];
9
- if (props.grameneConsequences && props.grameneConsequences[gene._id]) {
49
+ if (props.grameneConsequences && props.grameneConsequences[gene._id] && props.grameneGermplasm) {
50
+ const germplasmLUT = props.grameneGermplasm;
10
51
  const vep_obj = props.grameneConsequences[gene._id];
11
- let table = [];
52
+ let accessionTable = [];
53
+ let tableFields = [
54
+ { field: 'Order Germplasm', cellRenderer: metaRenderer, comparator: sortByLabel},
55
+ { field: 'Synonyms', cellRenderer: metaRenderer, comparator: sortByLabel},
56
+ { field: 'Study/Population', cellRenderer: metaRenderer, comparator: sortByLabel},
57
+ { field: 'VEP consequence', cellRenderer: metaRenderer, comparator: sortByLabel},
58
+ { field: 'Allele Status', cellRenderer: metaRenderer, comparator: sortByLabel},
59
+ { field: 'All LOF Genes', cellRenderer: metaRenderer, comparator: sortByLabel}
60
+ ];
12
61
  Object.entries(vep_obj).forEach(([key,accessions]) => {
13
62
  const parts = key.split("__");
14
63
  if (parts[0] === "VEP") {
15
64
  if (parts[1] !== "merged") {
16
- accessions.forEach(accession => {
17
- table.push({
18
- "study/pop": parts[3],
19
- "consequence": parts[1],
20
- "homo/het": parts[2],
21
- "acc_id": accession,
22
- "search": "button to search for genes with PTV in this accession"
23
- })
65
+ accessions.forEach(ens_id => {
66
+ const germplasm = germplasmLUT[ens_id][0];
67
+ const accInfo = {
68
+ 'Study/Population': {label: study_info[parts[3]].label},
69
+ 'VEP consequence': {label: parts[1].replaceAll("_"," ")},
70
+ 'Allele Status': {label: parts[2] === "het" ? "heterozygous" : "homozygous"},
71
+ 'Order Germplasm': {field: 'germplasm', gene_id: props.searchResult.id, label: germplasm.pub_id, ...germplasm},
72
+ 'All LOF Genes': {field: 'search', label: germplasm.ens_id, ...germplasm},
73
+ 'Synonyms': {label: germplasm.ens_id}
74
+ };
75
+ accessionTable.push(accInfo);
24
76
  });
25
77
  }
26
78
  }
27
79
  });
28
- return <pre>{JSON.stringify(table,null,2)}</pre>
80
+ // const [rowData, setRowData] = useState(accessionTable);
81
+ // const [colDefs, setColDefs] = useState(tableFields);
82
+ const defaultColDef = useMemo(() => {
83
+ return {
84
+ filter: true
85
+ }
86
+ }, []);
87
+ return <div>
88
+ <h5>Predicted loss-of-function alleles were detected in these germplasm.</h5>
89
+ <div >Explore other variants within this gene in the <a target="_blank"
90
+ href={`${props.configuration.ensemblURL}/${gene.system_name}/Gene/Variation_Gene/Image?db=core;g=${props.searchResult.id}`}>
91
+ Variant image</a> page on the Ensembl site.</div>
92
+ <div className="ag-theme-quartz" style={{height: `${44 * (accessionTable.length + 2)}px`}}>
93
+ <AgGridReact rowData={accessionTable} columnDefs={tableFields} defaultColDef={defaultColDef}/>
94
+ </div>
95
+ </div>
29
96
  } else {
30
97
  props.doRequestVEP(gene._id);
31
98
  return <pre>loading</pre>;
@@ -35,6 +102,7 @@ const Detail = props => {
35
102
  export default connect(
36
103
  'selectConfiguration',
37
104
  'selectGrameneConsequences',
105
+ 'selectGrameneGermplasm',
38
106
  'doRequestVEP',
39
107
  Detail
40
108
  );
package/src/demo.js CHANGED
@@ -116,7 +116,7 @@ const panSites = [
116
116
  url: 'https://www.sorghumbase.org',
117
117
  ensemblURL: 'https://ensembl-dev.sorghumbase.org',
118
118
  ensemblSite: 'https://ensembl-dev.sorghumbase.org',
119
- ensemblRest: 'https://data.gramene.org/pansite-ensembl',
119
+ ensemblRest: 'https://data.gramene.org/pansite-ensembl-87',
120
120
  grameneData: 'https://data.sorghumbase.org/sorghum_v7',
121
121
  ga: 'G-L5KXDCCZ16',
122
122
  targetTaxonId: 4558003,