grnsight 5.1.0 → 6.0.0

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.
Files changed (31) hide show
  1. package/.travis.yml +2 -0
  2. package/README.md +2 -2
  3. package/database/README.md +1 -0
  4. package/database/network-database/README.md +44 -0
  5. package/database/network-database/schema.sql +24 -0
  6. package/database/network-database/scripts/filter_genes.py +76 -0
  7. package/database/network-database/scripts/generate_network.py +199 -0
  8. package/database/network-database/scripts/generate_sgd_network_from_yeastract_network.py +120 -0
  9. package/database/network-database/scripts/loader.py +78 -0
  10. package/package.json +12 -12
  11. package/server/app.js +3 -1
  12. package/server/controllers/custom-workbook-controller.js +66 -0
  13. package/server/controllers/expression-database-controller.js +19 -0
  14. package/server/controllers/network-database-controller.js +18 -0
  15. package/server/{controllers/database-controller.js → dals/expression-dal.js} +27 -34
  16. package/server/dals/network-dal.js +96 -0
  17. package/test/api-tests.js +2 -5
  18. package/web-client/public/gene/api.js +1 -1
  19. package/web-client/public/js/api/grnsight-api.js +124 -0
  20. package/web-client/public/js/constants.js +7 -4
  21. package/web-client/public/js/createNetwork.js +195 -0
  22. package/web-client/public/js/grnsight.js +2 -0
  23. package/web-client/public/js/grnsight.min.js +33 -9
  24. package/web-client/public/js/grnstate.js +2 -1
  25. package/web-client/public/js/setup-load-and-import-handlers.js +32 -12
  26. package/web-client/public/js/update-app.js +38 -92
  27. package/web-client/public/js/upload.js +12 -8
  28. package/web-client/public/stylesheets/grnsight.styl +151 -3
  29. package/web-client/views/components/demo.pug +10 -0
  30. package/web-client/views/info.pug +1 -1
  31. package/web-client/views/upload.pug +125 -132
@@ -0,0 +1,195 @@
1
+ import {CREATE_NETWORK_CLASS, CREATE_NETWORK_MODAL} from "./constants";
2
+ import { queryNetworkDatabase, uploadCustomWorkbook } from "./api/grnsight-api";
3
+ import { grnState } from "./grnstate";
4
+
5
+ export const createNetwork = function () {
6
+ const createHTMLforForm = (sources) => {
7
+ let result = `
8
+ <div id=\'createNetworkFormContainer\' '>
9
+ <h2 id=\'createNetwork\'>Create Network</h2>
10
+ <div class=\'form-group\'>
11
+ <label for=\'network-source\' id=\'network-source-label\'>Network Source</label>
12
+ <select class=\'network-dropdown btn btn-default\' id=\'network-source\'>
13
+ `;
14
+ if (sources.length !== 1) {
15
+ result += "<option value=\'none\' selected=\'true\' disabled>Select Network Source</option>";
16
+ for (let source in sources) {
17
+ result += `
18
+ <option value=\'${sources[source]}\'>${sources[source]}</option>
19
+ `;
20
+ }
21
+ } else {
22
+ result += `
23
+ <option value=\'${sources[0]}\' selected=\'true\' disabled hidden>${sources[0]}</option>
24
+ `;
25
+ }
26
+ result += `</select>
27
+ <p>Warning: changing network source will remove all current genes in network</p>
28
+ </div>
29
+ <div class=\'form-group\' id=\'getNetworkGenesForm\'>
30
+ <form id=\'getNetworkGenesForm\'>
31
+ <label for=\'network-search-bar\' id=\'network-source-label\'>Select genes</label>
32
+ <input type=\'text\' id=\'network-search-bar\' name=\'network-search-bar\'></input>
33
+ <button id=\'enter-search\' type=\'submit\' class=\'search-button btn btn-default\'>
34
+ <span class=\'glyphicon glyphicon-search\'></span>
35
+ </button>
36
+ </form>
37
+ </div>
38
+ <div id=\'selected-genes-container\'>
39
+ <div id=\'selected-genes\'>
40
+ <p>Added genes go here! Click on a gene to remove it</p>
41
+ </div>
42
+ </div>
43
+ <button id=\'submit-network\' class=\'btn btn-default\'>Create Network</input>
44
+ </div>
45
+ `;
46
+ return result;
47
+ };
48
+ const createGeneButtons = function () {
49
+ let result = `<div id=\'selected-genes\'>
50
+ <p>Added genes go below! Click on a gene to remove it.</p>
51
+ <div id=\'custom-network-genes-container\'>
52
+ `;
53
+ for (let gene in grnState.customWorkbook.genes) {
54
+ result += `
55
+ <div class=\'custom-network-gene\' id=${gene}>
56
+ <p class=\'custom-network-gene-display-id\'>
57
+ ${grnState.customWorkbook.genes[gene]}
58
+ </p>
59
+ <p class=\'custom-network-gene-id\'>
60
+ (${gene})
61
+ </p>
62
+ </div>
63
+ `;
64
+ }
65
+
66
+ result += "</div></div>";
67
+ return result;
68
+ };
69
+ const displayCurrentGenes = function () {
70
+ $("#selected-genes").remove();
71
+ $("#selected-genes-container").append(createGeneButtons());
72
+ for (let gene in grnState.customWorkbook.genes) {
73
+ $(`#${gene}`).on("click", (ev) => {
74
+ ev.stopPropagation();
75
+ $(`#${gene}`).remove();
76
+ delete grnState.customWorkbook.genes[gene];
77
+ });
78
+ }
79
+ };
80
+
81
+ const addGene = function () {
82
+ let gene = `${$("#network-search-bar").val()}`.toUpperCase();
83
+ $("#network-search-bar").val("");
84
+ if (!(/^[A-Z0-9_-]{1,12}$/.test(gene))) {
85
+ alert(`Gene: ${gene} is not to GRNsight specifications. Genes must be 12 characters or less,
86
+ containing "-", "_", and alpha-numeric characters only`);
87
+ } else {
88
+ let source = grnState.customWorkbook.source;
89
+ let headers = {
90
+ type:"NetworkGeneFromSource",
91
+ info: {
92
+ gene: gene,
93
+ source:grnState.customWorkbook.sources[source].source,
94
+ timestamp:grnState.customWorkbook.sources[source].timestamp.substring(0, 19).replace("T", " ")
95
+ }
96
+ };
97
+ queryNetworkDatabase(headers).then(function (response) {
98
+ if (response.geneId !== null && response.displayGeneId !== null) {
99
+ grnState.customWorkbook.genes[response.geneId] = response.displayGeneId;
100
+ displayCurrentGenes();
101
+ } else {
102
+ alert(`Gene: ${gene} was not found in this database. Please check for any typos and try again.`);
103
+ }
104
+ }).catch(function (error) {
105
+ console.log(error.stack);
106
+ console.log(error.name);
107
+ console.log(error.message);
108
+ });
109
+
110
+ }
111
+ };
112
+
113
+ const displayCreateNetworkModal = function () {
114
+ $("#createNetworkFormContainer").remove();
115
+ grnState.customWorkbook = {
116
+ genes : {},
117
+ source : null
118
+ };
119
+ // get sources from database
120
+ queryNetworkDatabase({type:"NetworkSource", info:null}).then(function (response) {
121
+ $("#createNetworkQuestions-container").append(createHTMLforForm(Object.keys(response.sources)));
122
+ grnState.customWorkbook.sources = response.sources;
123
+ grnState.customWorkbook.source = Object.keys(response.sources).length === 1 ?
124
+ Object.keys(response.sources)[0] : null;
125
+ }).catch(function (error) {
126
+ console.log(error.stack);
127
+ console.log(error.name);
128
+ console.log(error.message);
129
+ });
130
+ $(CREATE_NETWORK_MODAL).modal("show");
131
+ };
132
+
133
+ $("body").on("click", CREATE_NETWORK_CLASS, function (event) {
134
+ event.preventDefault();
135
+ event.stopPropagation();
136
+ displayCreateNetworkModal();
137
+ });
138
+
139
+ $("body").on("change", "#network-source", function (event) {
140
+ grnState.customWorkbook.source = $("#network-source").val();
141
+ grnState.customWorkbook.genes = {};
142
+ event.stopPropagation();
143
+ displayCurrentGenes();
144
+ });
145
+ $("body").on("click", "#submit-network", function () {
146
+ let genesAmount = Object.keys(grnState.customWorkbook.genes).length;
147
+ if (genesAmount === 0 ) {
148
+ alert("Network must have at least 1 gene");
149
+ } else if (genesAmount > 75) {
150
+ alert(`GRNsight is only capable of handling 75 genes at most. Your proposed network contains
151
+ ${genesAmount} genes. Please remove some genes from your proposed network.`);
152
+ } else {
153
+
154
+ let source = grnState.customWorkbook.source;
155
+ let headers = {
156
+ type:"CreateNetwork",
157
+ info: {
158
+ genes: grnState.customWorkbook.genes,
159
+ source:grnState.customWorkbook.sources[source].source,
160
+ timestamp:grnState.customWorkbook.sources[source].timestamp.substring(0, 19).replace("T", " ")
161
+ }
162
+ };
163
+ queryNetworkDatabase(headers).then(function (response) {
164
+ grnState.customWorkbook.links = response.links;
165
+ let genes = grnState.customWorkbook.genes;
166
+ let links = grnState.customWorkbook.links;
167
+ let genesAmount = Object.keys(genes).length;
168
+ let edgesAmount = Object.keys(links).length;
169
+ if (edgesAmount > 100) {
170
+ alert(`GRNsight is only capable of handling 100 edges at most. Your proposed network contains
171
+ ${edgesAmount} regulatory connections. Please remove some genes from your proposed network.`);
172
+ } else {
173
+ let name = `Custom Workbook: UnweightedGRN(${genesAmount} genes, ${edgesAmount} edges)`;
174
+ let workbook = {name, genes, links};
175
+ uploadCustomWorkbook(workbook, grnState);
176
+ $(CREATE_NETWORK_MODAL).modal("hide");
177
+ }
178
+ }).catch(function (error) {
179
+ console.log(error.stack);
180
+ console.log(error.name);
181
+ console.log(error.message);
182
+ });
183
+ }
184
+ });
185
+
186
+ $("body").on("click", "#enter-search", function (event) {
187
+ try {
188
+ event.preventDefault();
189
+ event.stopPropagation();
190
+ addGene();
191
+ } catch (error) {
192
+ console.log(error);
193
+ }
194
+ });
195
+ };
@@ -1,5 +1,6 @@
1
1
  import { displayStatistics } from "./graph-statistics"; // eslint-disable-line no-unused-vars
2
2
  import { upload } from "./upload";
3
+ import { createNetwork } from "./createNetwork";
3
4
 
4
5
  import { grnState } from "./grnstate";
5
6
  import { updateApp } from "./update-app";
@@ -9,3 +10,4 @@ setupHandlers(grnState);
9
10
  updateApp(grnState);
10
11
 
11
12
  upload();
13
+ createNetwork();