@sjcrh/proteinpaint-shared 2.187.0 → 2.188.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.
Files changed (117) hide show
  1. package/README.md +10 -2
  2. package/constants/AiHisto.ts +27 -0
  3. package/constants/README.md +11 -0
  4. package/devTs.ts +3 -0
  5. package/dist/constants/AiHisto.d.ts +23 -0
  6. package/dist/constants/AiHisto.js +31 -0
  7. package/dist/constants/AiHisto.js.map +7 -0
  8. package/dist/src/aiHisto.d.ts +5 -0
  9. package/dist/src/aiHisto.js +15 -0
  10. package/dist/src/aiHisto.js.map +7 -0
  11. package/dist/src/bulk.cnv.js +83 -0
  12. package/dist/src/bulk.cnv.js.map +7 -0
  13. package/dist/src/bulk.del.js +119 -0
  14. package/dist/src/bulk.del.js.map +7 -0
  15. package/dist/src/bulk.itd.js +119 -0
  16. package/dist/src/bulk.itd.js.map +7 -0
  17. package/dist/src/bulk.js +183 -0
  18. package/dist/src/bulk.js.map +7 -0
  19. package/dist/src/bulk.snv.js +175 -0
  20. package/dist/src/bulk.snv.js.map +7 -0
  21. package/dist/src/bulk.sv.js +266 -0
  22. package/dist/src/bulk.sv.js.map +7 -0
  23. package/dist/src/bulk.svjson.js +151 -0
  24. package/dist/src/bulk.svjson.js.map +7 -0
  25. package/dist/src/bulk.trunc.js +122 -0
  26. package/dist/src/bulk.trunc.js.map +7 -0
  27. package/dist/src/clustering.js +71 -0
  28. package/dist/src/clustering.js.map +7 -0
  29. package/dist/src/common.js +1302 -0
  30. package/dist/src/common.js.map +7 -0
  31. package/dist/src/compute.percentile.js +10 -0
  32. package/dist/src/compute.percentile.js.map +7 -0
  33. package/dist/src/doc.d.ts +7 -0
  34. package/dist/src/doc.js +10 -0
  35. package/dist/src/doc.js.map +7 -0
  36. package/dist/src/fetch-helpers.js +177 -0
  37. package/dist/src/fetch-helpers.js.map +7 -0
  38. package/dist/src/fileSize.js +10 -0
  39. package/dist/src/fileSize.js.map +7 -0
  40. package/dist/src/filter.d.ts +62 -0
  41. package/dist/src/filter.js +194 -0
  42. package/dist/src/filter.js.map +7 -0
  43. package/dist/src/hash.js +20 -0
  44. package/dist/src/hash.js.map +7 -0
  45. package/dist/src/helpers.js +66 -0
  46. package/dist/src/helpers.js.map +7 -0
  47. package/dist/src/index.d.ts +26 -0
  48. package/dist/src/index.js +27 -0
  49. package/dist/src/index.js.map +7 -0
  50. package/dist/src/joinUrl.d.ts +1 -0
  51. package/dist/src/joinUrl.js +17 -0
  52. package/dist/src/joinUrl.js.map +7 -0
  53. package/dist/src/mds3tk.js +64 -0
  54. package/dist/src/mds3tk.js.map +7 -0
  55. package/dist/src/roundValue.js +57 -0
  56. package/dist/src/roundValue.js.map +7 -0
  57. package/dist/src/termdb.bins.js +272 -0
  58. package/dist/src/termdb.bins.js.map +7 -0
  59. package/dist/src/termdb.initbinconfig.js +79 -0
  60. package/dist/src/termdb.initbinconfig.js.map +7 -0
  61. package/dist/src/termdb.usecase.js +239 -0
  62. package/dist/src/termdb.usecase.js.map +7 -0
  63. package/dist/src/terms.d.ts +83 -0
  64. package/dist/src/terms.js +327 -0
  65. package/dist/src/terms.js.map +7 -0
  66. package/dist/src/time.d.ts +9 -0
  67. package/dist/src/time.js +23 -0
  68. package/dist/src/time.js.map +7 -0
  69. package/dist/src/tree.js +82 -0
  70. package/dist/src/tree.js.map +7 -0
  71. package/dist/src/urljson.d.ts +8 -0
  72. package/dist/src/urljson.js +31 -0
  73. package/dist/src/urljson.js.map +7 -0
  74. package/dist/src/vcf.ann.js +56 -0
  75. package/dist/src/vcf.ann.js.map +7 -0
  76. package/dist/src/vcf.csq.js +82 -0
  77. package/dist/src/vcf.csq.js.map +7 -0
  78. package/dist/src/vcf.info.js +40 -0
  79. package/dist/src/vcf.info.js.map +7 -0
  80. package/dist/src/vcf.js +439 -0
  81. package/dist/src/vcf.js.map +7 -0
  82. package/dist/src/vcf.type.js +17 -0
  83. package/dist/src/vcf.type.js.map +7 -0
  84. package/package.json +20 -11
  85. package/src/bulk.cnv.js +0 -86
  86. package/src/bulk.del.js +0 -124
  87. package/src/bulk.itd.js +0 -123
  88. package/src/bulk.js +0 -197
  89. package/src/bulk.snv.js +0 -271
  90. package/src/bulk.sv.js +0 -276
  91. package/src/bulk.svjson.js +0 -164
  92. package/src/bulk.trunc.js +0 -132
  93. package/src/clustering.js +0 -66
  94. package/src/common.js +0 -1608
  95. package/src/compute.percentile.js +0 -11
  96. package/src/doc.js +0 -6
  97. package/src/fetch-helpers.js +0 -323
  98. package/src/fileSize.js +0 -6
  99. package/src/filter.js +0 -221
  100. package/src/hash.js +0 -21
  101. package/src/helpers.js +0 -88
  102. package/src/index.js +0 -26
  103. package/src/joinUrl.js +0 -14
  104. package/src/mds3tk.js +0 -100
  105. package/src/roundValue.js +0 -94
  106. package/src/termdb.bins.js +0 -456
  107. package/src/termdb.initbinconfig.js +0 -130
  108. package/src/termdb.usecase.js +0 -344
  109. package/src/terms.js +0 -341
  110. package/src/time.js +0 -22
  111. package/src/tree.js +0 -138
  112. package/src/urljson.js +0 -41
  113. package/src/vcf.ann.js +0 -62
  114. package/src/vcf.csq.js +0 -153
  115. package/src/vcf.info.js +0 -50
  116. package/src/vcf.js +0 -654
  117. package/src/vcf.type.js +0 -24
@@ -1,130 +0,0 @@
1
- /*
2
- Initialize a bin configuration for a numeric dataset
3
- <data>: array of numeric data values
4
- <opts> (optional): object of options
5
- {}: output bin config as JavaScript object (default)
6
- {format: 'string'}: output bin config as JSON string
7
- */
8
- export default function initBinConfig(data, opts = {}) {
9
- if (!data.length)
10
- return {
11
- mode: "discrete",
12
- type: "regular-bin",
13
- startinclusive: true,
14
- bin_size: null,
15
- first_bin: { stop: null },
16
- }
17
- if (data.find((d) => !Number.isFinite(d)))
18
- throw new Error("non-numeric values found")
19
-
20
- let binConfig
21
- const s = new Set(data)
22
- if (s.size === 1) {
23
- // single unique value in data array
24
- // prepare custom bin config for 3 bins: first bin
25
- // for values less than the value, second bin for values
26
- // equal to the value, and third bin one for values
27
- // greater than the value
28
- // all data values will fall into the second bin
29
- const value = [...s][0]
30
- binConfig = {
31
- type: "custom-bin",
32
- lst: [
33
- {
34
- stop: value,
35
- stopinclusive: false,
36
- startunbounded: true,
37
- label: "<" + value,
38
- },
39
- {
40
- start: value,
41
- stop: value,
42
- startinclusive: true,
43
- stopinclusive: true,
44
- label: "=" + value,
45
- },
46
- {
47
- start: value,
48
- startinclusive: false,
49
- stopunbounded: true,
50
- label: ">" + value,
51
- },
52
- ],
53
- }
54
- } else {
55
- // multiple unique values in data array
56
- // prepare regular bin config
57
-
58
- // compute the bin size for a maximum bin number of 8
59
- data.sort((a, b) => a - b)
60
- const l = data.length
61
- const min = data[0]
62
- const max = data[l - 1]
63
- const p5idx = Math.ceil(l * 0.05) - 1
64
- const p98idx = Math.ceil(l * 0.98) - 1
65
- const p5 = data[p5idx]
66
- const p98 = data[p98idx]
67
- // use 98th and 5th percentiles to compute bin size to reduce outlier influence
68
- // if 98th = 5th, use max and min instead
69
- const binSize = p98 != p5 ? (p98 - p5) / 8 : (max - min) / 8
70
- // first bin stop will equal either (minimum + bin size) or (5th percentile), whichever is larger.
71
- const firstBinStop = Math.max(min + binSize, p5)
72
- // round the bin values
73
- let [binSize_rnd, firstBinStop_rnd, lastBinStart_rnd, rounding] =
74
- roundBinVals(binSize, firstBinStop, max, min)
75
- // generate the bin configuration
76
- binConfig = {
77
- type: "regular-bin",
78
- startinclusive: true,
79
- bin_size: binSize_rnd,
80
- first_bin: { stop: firstBinStop_rnd },
81
- }
82
- if (lastBinStart_rnd) binConfig.last_bin = { start: lastBinStart_rnd }
83
- if (rounding) binConfig.rounding = rounding
84
- }
85
- if ("format" in opts) {
86
- if (opts.format === "string") {
87
- return JSON.stringify(binConfig)
88
- } else {
89
- throw "options are not in the correct format"
90
- }
91
- } else {
92
- return binConfig
93
- }
94
- }
95
-
96
- function roundBinVals(binSize, firstBinStop, max, min) {
97
- let binSize_rnd, firstBinStop_rnd, lastBinStart_rnd, rounding
98
- const log = Math.floor(Math.log10(binSize))
99
- if (binSize >= 0.1 && binSize <= 2) {
100
- // Round to the nearest one for small bin sizes
101
- binSize_rnd = Math.round(binSize / (1 * 10 ** log)) * (1 * 10 ** log)
102
- firstBinStop_rnd =
103
- Math.round(firstBinStop / (1 * 10 ** log)) * (1 * 10 ** log)
104
- } else {
105
- // Round to the nearest five for large bin sizes
106
- binSize_rnd = Math.round(binSize / (5 * 10 ** log)) * (5 * 10 ** log)
107
- firstBinStop_rnd =
108
- Math.round(firstBinStop / (5 * 10 ** log)) * (5 * 10 ** log)
109
- if (binSize_rnd === 0) binSize_rnd = 1 * 10 ** log
110
- if (firstBinStop_rnd === 0) firstBinStop_rnd = 1 * 10 ** log
111
- if (binSize_rnd === 5 * 10 ** log && firstBinStop_rnd === 1 * 10 ** log)
112
- firstBinStop_rnd = 5 * 10 ** log
113
- }
114
- if (firstBinStop_rnd < min) firstBinStop_rnd = firstBinStop_rnd * 2
115
- // if the number of bins is above 8 after rounding, then set the last bin start to restrict the number of bins to 8
116
- const eighthBinStop_rnd = firstBinStop_rnd + binSize_rnd * 7
117
- if (max > eighthBinStop_rnd) {
118
- lastBinStart_rnd = firstBinStop_rnd + binSize_rnd * 6
119
- }
120
- if (binSize < 1) {
121
- const digits = Math.abs(log)
122
- binSize_rnd = Number(binSize_rnd.toFixed(digits))
123
- firstBinStop_rnd = Number(firstBinStop_rnd.toFixed(digits))
124
- if (lastBinStart_rnd)
125
- lastBinStart_rnd = Number(lastBinStart_rnd.toFixed(digits))
126
- rounding = "." + digits + "f"
127
- }
128
- if (Object.is(firstBinStop_rnd, -0)) firstBinStop_rnd = 0
129
- return [binSize_rnd, firstBinStop_rnd, lastBinStart_rnd, rounding]
130
- }
@@ -1,344 +0,0 @@
1
- import {
2
- TermTypes,
3
- isNumericTerm,
4
- SINGLECELL_CELLTYPE,
5
- SINGLECELL_GENE_EXPRESSION,
6
- ISOFORM_EXPRESSION,
7
- } from "./terms.js"
8
-
9
- export const graphableTypes = new Set([
10
- "categorical",
11
- "integer",
12
- "float",
13
- "condition",
14
- "survival",
15
- "snplst",
16
- "snplocus",
17
- "geneVariant",
18
- "samplelst",
19
- "geneExpression",
20
- ISOFORM_EXPRESSION,
21
- "dtcnv",
22
- "dtsnvindel",
23
- "dtfusion",
24
- "dtsv",
25
- "date",
26
- TermTypes.SSGSEA,
27
- TermTypes.DNA_METHYLATION,
28
- TermTypes.METABOLITE_INTENSITY,
29
- TermTypes.PROTEOME_ABUNDANCE,
30
- SINGLECELL_GENE_EXPRESSION,
31
- SINGLECELL_CELLTYPE,
32
- TermTypes.SNP,
33
- TermTypes.TERM_COLLECTION,
34
- ])
35
-
36
- /*
37
- isUsableTerm() will
38
-
39
- - centralize the "allowed term" logic
40
- which can be intricate or dataset-specific
41
- for certain terms or contexts
42
- - make it easy to handle new term types
43
-
44
- Arguments:
45
-
46
- term {}
47
- .type: 'categorical', etc.
48
- .child_types: []
49
-
50
- _usecase {}
51
- .target (REQUIRED): 'barchart', 'regression', etc
52
- - used as a switch-case "router" for additional use-specific logic
53
- - other parameters, if applicable, are described in the route "handler"
54
- .detail
55
- - a more specific detailed use case
56
-
57
-
58
- termdbConfig
59
- optional. provides ds overrides on default rules via excludedTermtypeByTarget. for use on client
60
-
61
- ds
62
- optional. provides ds overrides when the function runs on backend
63
- server-side dataset object that can supply overrides (in the form of functions) to the use case logic,
64
- for example, to apply role-based allowed term uses or performance-related restrictions
65
- to ancestor terms when a use case aggregates too many data points for a given chart type
66
-
67
- Returns
68
-
69
- a Set{} with zero or more of the following strings:
70
- - 'plot' if the term can be used in a plot chartType
71
- - 'branch' if the term can be used only as an expandable tree branch, but not in a plot
72
- - an empty Set means that the term has no valid uses, i.e, it cannot be used either for plotting or as a tree branch
73
- */
74
- export function isUsableTerm(term, _usecase, termdbConfig, ds) {
75
- const usecase = _usecase || {}
76
-
77
- // may apply dataset specific override filter for a use case
78
- if (typeof ds?.usecase?.[usecase.target] == "function") {
79
- return ds.usecase[usecase.target](term, usecase)
80
- }
81
-
82
- // if (term.isprivate && !user.roleCanUse(term)) return false
83
-
84
- const uses = new Set()
85
- // note: expects term.child_types to be null if term.isleaf == true
86
- const child_types = term.child_types || []
87
- // default handling
88
- switch (usecase.target) {
89
- case "barchart":
90
- case "violin":
91
- case "boxplot":
92
- case "summary":
93
- if (term.type && term.type !== "survival") uses.add("plot")
94
- if (hasAllowedChildTypes(child_types, ["survival"])) uses.add("branch")
95
- return uses
96
-
97
- case "summaryInput":
98
- if (usecase.detail === "term2" || usecase.detail == "term0") {
99
- if (term.type && term.type !== "survival") uses.add("plot")
100
- if (hasAllowedChildTypes(child_types, ["survival"])) uses.add("branch")
101
- return uses
102
- } else {
103
- if (graphableTypes.has(term.type)) uses.add("plot")
104
- if (!term.isleaf) uses.add("branch")
105
- return uses
106
- }
107
-
108
- case "matrix":
109
- if (term.type) uses.add("plot")
110
- if (!term.isleaf) uses.add("branch")
111
- return uses
112
-
113
- case "table":
114
- if (usecase.detail == "term") uses.add("plot")
115
- if (child_types.length > 1) uses.add("branch")
116
- return uses
117
-
118
- case "sampleScatter":
119
- if (usecase.detail == "numeric") {
120
- if (isNumericTerm(term)) {
121
- uses.add("plot")
122
- }
123
- if (hasNumericChild(child_types)) uses.add("branch")
124
- }
125
- // Commenting out for now. May need later for another single
126
- // cell term. Revisit logic at that time.
127
- // else if (usecase?.specialCase?.type == 'singleCell') {
128
- // if (term.type && term.type.startsWith('singleCell')) {
129
- // if (term.plot && term.plot == usecase.specialCase?.config.name) {
130
- // uses.add('plot')
131
- // }
132
- // }
133
- // }
134
- else {
135
- if (graphableTypes.has(term.type)) uses.add("plot")
136
- if (!term.isleaf) uses.add("branch")
137
- }
138
- return uses
139
- case "runChart2":
140
- if (usecase.detail == "date" || usecase.detail == "xtw") {
141
- if (term.type == "date") {
142
- uses.add("plot")
143
- }
144
- if (child_types.includes("date")) uses.add("branch")
145
- } else if (usecase.detail == "numeric") {
146
- if (isNumericTerm(term) && term.type != "date") {
147
- uses.add("plot")
148
- }
149
- if (hasNumericChild(child_types)) uses.add("branch")
150
- } else {
151
- if (graphableTypes.has(term.type)) uses.add("plot")
152
- if (!term.isleaf) uses.add("branch")
153
- }
154
- return uses
155
-
156
- case "numericDictTermCluster":
157
- if (!usecase.detail?.exclude?.includes(term.id)) {
158
- if (isNumericTerm(term)) {
159
- uses.add("plot")
160
- }
161
- if (hasNumericChild(child_types)) {
162
- uses.add("branch")
163
- }
164
- }
165
- return uses
166
-
167
- case "termCollections":
168
- if (usecase.detail?.termIds?.includes(term.id)) uses.add("plot")
169
- if (usecase.detail?.branchIds?.includes(term.id)) uses.add("branch")
170
- return uses
171
-
172
- case "profileForms":
173
- if (!term.isleaf) {
174
- const ancestors = term.id.split("__").length //depends on using the __ naming convension!
175
- if (ancestors == 3) {
176
- // 3rd level term is a domain, we show the templates associated to this domain
177
- uses.add("plot")
178
- } else if (ancestors < 3) uses.add("branch")
179
- }
180
- return uses
181
-
182
- case "profileForms2": {
183
- // Picker (forms2.ts makeChartBtnMenu) sets usecase.cohort + usecase.subtype.
184
- // Reads the per-cohort domains list directly from the dataset config at
185
- // plotConfigByCohort[cohort].profileForms2.domains — each entry is { id, plotTypes }.
186
- if (term.isleaf) return uses
187
- const allowed =
188
- termdbConfig?.plotConfigByCohort?.[usecase.cohort]?.profileForms2
189
- ?.domains
190
- if (!allowed) return uses
191
- const ancestors = term.id.split("__").length
192
- const subtype = usecase.subtype
193
- if (ancestors == 3) {
194
- if (allowed.find((d) => d.id === term.id)?.plotTypes?.includes(subtype))
195
- uses.add("plot")
196
- } else if (ancestors < 3) {
197
- const prefix = term.id + "__"
198
- if (
199
- allowed.some(
200
- (d) => d.id.startsWith(prefix) && d.plotTypes.includes(subtype)
201
- )
202
- ) {
203
- uses.add("branch")
204
- }
205
- }
206
- return uses
207
- }
208
-
209
- // case 'boxplot':
210
- // if (term.type == 'float' || term.type == 'integer') uses.add('plot')
211
- // if (usecase.detail === 'term2' && hasNumericChild(child_types)) uses.add('branch')
212
- // return uses
213
-
214
- case "cuminc":
215
- if (usecase.detail == "term") {
216
- if (term.type == "condition") uses.add("plot")
217
- if (child_types.includes("condition")) uses.add("branch")
218
- return uses
219
- }
220
- if (usecase.detail === "term2" || usecase.detail == "term0") {
221
- if (term.type && term.type != "condition" && term.type != "survival")
222
- uses.add("plot")
223
- if (hasAllowedChildTypes(child_types, ["condition", "survival"]))
224
- uses.add("branch")
225
- return uses
226
- }
227
- return uses
228
-
229
- case "survival":
230
- if (usecase.detail == "term") {
231
- if (term.type == "survival") uses.add("plot")
232
- if (child_types.includes("survival")) uses.add("branch")
233
- return uses
234
- }
235
- if (usecase.detail === "term2" || usecase.detail == "term0") {
236
- if (term.type && term.type != "survival") uses.add("plot")
237
- if (hasAllowedChildTypes(child_types, ["survival"])) uses.add("branch")
238
- return uses
239
- }
240
- return uses
241
-
242
- case "regression":
243
- if (usecase.detail == "outcome") {
244
- if (usecase.regressionType == "linear") {
245
- if (term.type == "float" || term.type == "integer") uses.add("plot")
246
- if (hasNumericChild(child_types)) uses.add("branch")
247
- return uses
248
- }
249
- if (usecase.regressionType == "logistic") {
250
- if (term.type && term.type != "survival") uses.add("plot")
251
- if (hasAllowedChildTypes(child_types, ["survival"]))
252
- uses.add("branch")
253
- return uses
254
- } else if (usecase.regressionType == "cox") {
255
- if (term.type == "condition" || term.type == "survival")
256
- uses.add("plot")
257
- if (
258
- child_types.includes("condition") ||
259
- child_types.includes("survival")
260
- )
261
- uses.add("branch")
262
- return uses
263
- }
264
- }
265
-
266
- if (usecase.detail == "independent") {
267
- if (
268
- term.type == "float" ||
269
- term.type == "integer" ||
270
- term.type == "categorical" ||
271
- term.type == "samplelst"
272
- )
273
- uses.add("plot")
274
- if (hasChildTypes(child_types, ["categorical", "float", "integer"]))
275
- uses.add("branch")
276
- return uses
277
- }
278
- return uses
279
-
280
- case "filter": {
281
- // apply "exlst" to other targets as needed
282
- const exlst = termdbConfig?.excludedTermtypeByTarget?.filter
283
- if (exlst) {
284
- if (graphableTypes.has(term.type) && !exlst.includes(term.type))
285
- uses.add("plot")
286
- if (child_types.find((t) => !exlst.includes(t))) uses.add("branch") // there's a non-excluded child type, allow branch to show
287
- return uses
288
- }
289
- // no specific rule for filter. use default rules
290
- if (graphableTypes.has(term.type)) uses.add("plot")
291
- if (!term.isleaf) uses.add("branch")
292
- return uses
293
- }
294
-
295
- case "correlationVolcano":
296
- if (usecase.detail == "numeric") {
297
- if (isNumericTerm(term)) {
298
- uses.add("plot")
299
- }
300
- if (hasNumericChild(child_types)) uses.add("branch")
301
- } else {
302
- if (graphableTypes.has(term.type)) uses.add("plot")
303
- if (!term.isleaf) uses.add("branch")
304
- }
305
- return uses
306
-
307
- case "proteinView":
308
- if (term.type == TermTypes.PROTEOME_ABUNDANCE) uses.add("plot")
309
- if (child_types.includes(TermTypes.PROTEOME_ABUNDANCE)) uses.add("branch")
310
- return uses
311
-
312
- default:
313
- if (graphableTypes.has(term.type)) uses.add("plot")
314
- if (!term.isleaf) uses.add("branch")
315
- return uses
316
- }
317
- }
318
-
319
- // determine if the term has at least one child type that
320
- // is not excluded
321
- function hasAllowedChildTypes(child_types, excluded_types) {
322
- if (!child_types.length) {
323
- // term does not have children
324
- return false
325
- }
326
- if (!excluded_types?.length) {
327
- // no excluded types
328
- return true
329
- }
330
- if (child_types.some((type) => !excluded_types.includes(type))) {
331
- // at least one child type is not excluded
332
- return true
333
- }
334
- }
335
-
336
- function hasNumericChild(child_types) {
337
- return child_types.includes("float") || child_types.includes("integer")
338
- }
339
-
340
- function hasChildTypes(child_types, expected_types) {
341
- for (const a of expected_types) {
342
- if (child_types.includes(a)) return true
343
- }
344
- }