@platforma-open/milaboratories.top-antibodies.workflow 1.1.0 → 1.2.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.
@@ -1,13 +1,17 @@
1
1
   WARN  Issue while reading "/home/runner/work/top-antibodies/top-antibodies/.npmrc". Failed to replace env in config: ${NPMJS_TOKEN}
2
2
 
3
- > @platforma-open/milaboratories.top-antibodies.workflow@1.1.0 build /home/runner/work/top-antibodies/top-antibodies/workflow
3
+ > @platforma-open/milaboratories.top-antibodies.workflow@1.2.0 build /home/runner/work/top-antibodies/top-antibodies/workflow
4
4
  > rm -rf dist && pl-tengo check && pl-tengo build
5
5
 
6
- info: Skipping unknown file type: wf.test.ts
7
6
  Processing "src/main.tpl.tengo"...
7
+ Processing "src/pf-umap-conv.lib.tengo"...
8
+ Processing "src/sampled-cols-conv.lib.tengo"...
9
+ Processing "src/sampled-cols-umap-conv.lib.tengo"...
8
10
  No syntax errors found.
9
- info: Skipping unknown file type: wf.test.ts
10
11
  info: Compiling 'dist'...
12
+ info: - writing /home/runner/work/top-antibodies/top-antibodies/workflow/dist/tengo/lib/pf-umap-conv.lib.tengo
13
+ info: - writing /home/runner/work/top-antibodies/top-antibodies/workflow/dist/tengo/lib/sampled-cols-conv.lib.tengo
14
+ info: - writing /home/runner/work/top-antibodies/top-antibodies/workflow/dist/tengo/lib/sampled-cols-umap-conv.lib.tengo
11
15
  info: - writing /home/runner/work/top-antibodies/top-antibodies/workflow/dist/tengo/tpl/main.plj.gz
12
- info:
16
+ info: Template Pack build done.
13
17
  info: Template Pack build done.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,24 @@
1
1
  # @platforma-open/milaboratories.top-antibodies.workflow
2
2
 
3
+ ## 1.2.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 5ee90ac: Add CDR3 spectratype
8
+
9
+ ### Patch Changes
10
+
11
+ - Updated dependencies [5ee90ac]
12
+ - @platforma-open/milaboratories.top-antibodies.spectratype@1.1.0
13
+
14
+ ## 1.1.1
15
+
16
+ ### Patch Changes
17
+
18
+ - 339a780: Main backbone
19
+ - Updated dependencies [339a780]
20
+ - @platforma-open/milaboratories.top-antibodies.software@1.0.1
21
+
3
22
  ## 1.1.0
4
23
 
5
24
  ### Minor Changes
@@ -0,0 +1,43 @@
1
+ ll := import("@platforma-sdk/workflow-tengo:ll")
2
+
3
+ getColumns := func(datasetSpec) {
4
+ return {
5
+ "axes": [
6
+ {
7
+ "column": "clonotypeKey",
8
+ "spec": datasetSpec.axesSpec[1]
9
+ }
10
+ ],
11
+ "columns": [
12
+ {
13
+ "column": "UMAP1",
14
+ "id": "umap1",
15
+ "allowNA": false,
16
+ "spec": {
17
+ "name": "pl7.app/vdj/umap1",
18
+ "valueType": "Double",
19
+ "annotations": {
20
+ "pl7.app/label": "UMAP Dim1"
21
+ }
22
+ }
23
+ },
24
+ {
25
+ "column": "UMAP2",
26
+ "id": "umap2",
27
+ "allowNA": false,
28
+ "spec": {
29
+ "name": "pl7.app/vdj/umap2",
30
+ "valueType": "Double",
31
+ "annotations": {
32
+ "pl7.app/label": "UMAP Dim2"
33
+ }
34
+ }
35
+ }],
36
+ "storageFormat": "Binary",
37
+ "partitionKeyLength": 0
38
+ }
39
+ }
40
+
41
+ export ll.toStrict({
42
+ getColumns: getColumns
43
+ })
@@ -0,0 +1,45 @@
1
+ ll := import("@platforma-sdk/workflow-tengo:ll")
2
+
3
+ getColumns := func(datasetSpec, linkerAxisSpec) {
4
+ axes := [
5
+ {
6
+ "column": "clonotypeKey",
7
+ "spec": datasetSpec.axesSpec[1]
8
+ }]
9
+
10
+ if len(linkerAxisSpec) > 0 {
11
+ for key, val in linkerAxisSpec {
12
+ axes = axes + [
13
+ {
14
+ "column": key,
15
+ "spec": val
16
+ }]
17
+ }
18
+
19
+ }
20
+ return {
21
+ "axes": axes,
22
+ "columns": [
23
+ {
24
+ "column": "top",
25
+ "id": "link",
26
+ "allowNA": false,
27
+ "spec": {
28
+ "name": "pl7.app/vdj/sampling-column",
29
+ "valueType": "Int",
30
+ "domain": {},
31
+ "annotations": {
32
+ "pl7.app/label": "Sampling column",
33
+ "pl7.app/table/visibility": "optional"
34
+ }
35
+ }
36
+ }
37
+ ],
38
+ "storageFormat": "Binary",
39
+ "partitionKeyLength": 0
40
+ }
41
+ }
42
+
43
+ export ll.toStrict({
44
+ getColumns: getColumns
45
+ })
@@ -0,0 +1,38 @@
1
+ ll := import("@platforma-sdk/workflow-tengo:ll")
2
+
3
+
4
+
5
+ getColumns := func(datasetSpec) {
6
+ axes := [
7
+ {
8
+ "column": "clonotypeKey",
9
+ "spec": datasetSpec.axesSpec[1]
10
+ }]
11
+
12
+ return {
13
+ "axes": axes,
14
+ "columns": [
15
+ {
16
+ "column": "top",
17
+ "id": "link2", // temporal change
18
+ "allowNA": false,
19
+ "spec": {
20
+ "name": "pl7.app/vdj/sampling-column-umap",
21
+ "valueType": "Int",
22
+ "domain": {},
23
+ "annotations": {
24
+ "pl7.app/label": "Top clonotypes",
25
+ "pl7.app/table/visibility": "optional",
26
+ "pl7.app/isSubset": "true"
27
+ }
28
+ }
29
+ }
30
+ ],
31
+ "storageFormat": "Binary",
32
+ "partitionKeyLength": 0
33
+ }
34
+ }
35
+
36
+ export ll.toStrict({
37
+ getColumns: getColumns
38
+ })
Binary file
package/package.json CHANGED
@@ -1,14 +1,17 @@
1
1
  {
2
2
  "name": "@platforma-open/milaboratories.top-antibodies.workflow",
3
- "version": "1.1.0",
3
+ "version": "1.2.0",
4
4
  "type": "module",
5
5
  "description": "Block Workflow",
6
6
  "dependencies": {
7
- "@platforma-sdk/workflow-tengo": "^4.0.2"
7
+ "@platforma-sdk/workflow-tengo": "^4.3.2",
8
+ "@platforma-open/milaboratories.top-antibodies.sample-clonotypes": "1.0.1",
9
+ "@platforma-open/milaboratories.top-antibodies.spectratype": "1.1.0",
10
+ "@platforma-open/milaboratories.top-antibodies.umap": "1.0.1"
8
11
  },
9
12
  "devDependencies": {
10
- "@platforma-sdk/tengo-builder": "^2.0.3",
11
- "@platforma-sdk/test": "^1.27.10",
13
+ "@platforma-sdk/tengo-builder": "^2.1.3",
14
+ "@platforma-sdk/test": "^1.30.24",
12
15
  "vitest": "^2.1.8"
13
16
  },
14
17
  "scripts": {
@@ -1,11 +1,309 @@
1
1
  // light block with no workflow
2
2
  wf := import("@platforma-sdk/workflow-tengo:workflow")
3
+ exec := import("@platforma-sdk/workflow-tengo:exec")
4
+ assets:= import("@platforma-sdk/workflow-tengo:assets")
5
+ xsv := import("@platforma-sdk/workflow-tengo:pframes.xsv")
6
+ pframes := import("@platforma-sdk/workflow-tengo:pframes")
7
+ sampledColsConv := import(":sampled-cols-conv")
8
+ sampledColsUmapConv := import(":sampled-cols-umap-conv")
9
+ slices := import("@platforma-sdk/workflow-tengo:slices")
10
+ umapConv := import(":pf-umap-conv")
11
+
12
+ wf.prepare(func(args){
13
+ // We need a table with cluster ID (optional) | clonotype id | selected ranking columns
14
+
15
+ bundleBuilder := wf.createPBundleBuilder()
16
+ bundleBuilder.ignoreMissingDomains() // to make query work for both bulk and single cell data
17
+ bundleBuilder.addAnchor("main", args.inputAnchor)
18
+
19
+ for col in args.rankingOrder {
20
+ bundleBuilder.addSingle(col)
21
+ }
22
+
23
+ // Add linker column
24
+ bundleBuilder.addMulti({
25
+ axes: [{ anchor: "main", idx: 1 }], // this will do partial axes match (unlike in the model)
26
+ annotations: { "pl7.app/isLinkerColumn": "true" },
27
+ partialAxesMatch: true
28
+ }, "linkers")
29
+
30
+ // Add full aa sequence column
31
+ bundleBuilder.addMulti({
32
+ axes: [{ anchor: "main", idx: 1 }],
33
+ annotations: {
34
+ "pl7.app/vdj/isAssemblingFeature": "true",
35
+ "pl7.app/vdj/isMainSequence": "true"
36
+ },
37
+ domain: {
38
+ "pl7.app/alphabet": "aminoacid"
39
+ }
40
+ }, "aaSequence")
41
+
42
+ // Add CDR3 sequences
43
+ bundleBuilder.addMulti({
44
+ axes: [{ anchor: "main", idx: 1 }], // Clonotype axis
45
+ name: "pl7.app/vdj/sequence",
46
+ domain: {
47
+ "pl7.app/alphabet": "aminoacid",
48
+ "pl7.app/vdj/feature": "CDR3" // Specify CDR3 feature
49
+ }
50
+ }, "cdr3Sequences") // New collection name for CDR3 sequences
51
+
52
+ // Add V gene
53
+ bundleBuilder.addMulti({
54
+ axes: [{ anchor: "main", idx: 1 }], // Clonotype axis
55
+ name: "pl7.app/vdj/geneHit",
56
+ domain: {
57
+ "pl7.app/vdj/reference": "VGene"
58
+ }
59
+ }, "VGenes")
60
+
61
+ return {
62
+ columns: bundleBuilder.build()
63
+ }
64
+ })
3
65
 
4
66
  wf.body(func(args) {
5
67
 
68
+ // Input arguments
69
+ columns := args.columns
70
+ datasetSpec := columns.getSpec(args.inputAnchor)
71
+
72
+ topClonotypes := args.topClonotypes
73
+
74
+ // Needed conditional variables
75
+ isSingleCell := datasetSpec.axesSpec[1].name == "pl7.app/vdj/scClonotypeKey"
76
+
77
+ // output containers
78
+ outputs := {}
79
+
80
+ ////////// Clonotype Filtering //////////
81
+
82
+ // Build clonotype table
83
+ cloneTable := columns.xsvTableBuilder()
84
+ cloneTable.setAxisHeader(datasetSpec.axesSpec[1].name, "clonotypeKey")
85
+
86
+ for i, col in args.rankingOrder {
87
+ cloneTable.add(col, {header: "Col" + string(i)})
88
+
89
+ // If column does not have main anchor axis we have to include theirs
90
+ colsSpec := columns.getSpec(col)
91
+ axesNames := slices.map(colsSpec.axesSpec, func (a) { return a.name})
92
+ if !slices.hasElement(axesNames, datasetSpec.axesSpec[1].name) {
93
+ for na, ax in colsSpec.axesSpec {
94
+ if ax.name != datasetSpec.axesSpec[1].name {
95
+ cloneTable.setAxisHeader(ax.name, "cluster_" + string(i) + string(na))
96
+ }
97
+ }
98
+ }
99
+ }
100
+
101
+ // Columns gotten by query require .key
102
+ linkerAxisSpec := {}
103
+ for i, col in columns.getColumns("linkers") {
104
+ if datasetSpec.axesSpec[1].name == col.spec.axesSpec[1].name {
105
+ cloneTable.add(col.key, {header: "linker." + string(i)})
106
+ cloneTable.setAxisHeader(col.spec.axesSpec[0].name, "cluster_" + string(i))
107
+ linkerAxisSpec["cluster_" + string(i)] = col.spec.axesSpec[0]
108
+ } else if datasetSpec.axesSpec[1].name == col.spec.axesSpec[0].name {
109
+ cloneTable.add(col.key, {header: "linker." + string(i)})
110
+ cloneTable.setAxisHeader(col.spec.axesSpec[1].name, "cluster_" + string(i))
111
+ linkerAxisSpec["cluster_" + string(i)] = col.spec.axesSpec[1]
112
+ }
113
+ }
114
+ cloneTable = cloneTable.build("csv")
115
+
116
+ if topClonotypes != undefined {
117
+ // Run sampling script
118
+ sampleClones := exec.builder().
119
+ software(assets.importSoftware("@platforma-open/milaboratories.top-antibodies.sample-clonotypes:main")).
120
+ addFile("filteredClonotypes.csv", cloneTable).
121
+ arg("--csv").arg("filteredClonotypes.csv").
122
+ arg("--n").arg(string(topClonotypes)).
123
+ arg("--out").arg("sampledClonotypes.csv").
124
+ saveFile("sampledClonotypes_top.csv").
125
+ printErrStreamToStdout().
126
+ saveStdoutContent().
127
+ cache(24 * 60 * 60 * 1000).
128
+ run()
129
+
130
+ // Store outputs
131
+ sampledColsParams := sampledColsConv.getColumns(datasetSpec, linkerAxisSpec)
132
+ sampledColumnsPf := xsv.importFile(sampleClones.getFile("sampledClonotypes_top.csv"), "csv", sampledColsParams)
133
+ outputs["sampledRows"] = pframes.exportFrame(sampledColumnsPf)
134
+
135
+ // Prepare filter col subset for UMAP
136
+ // Avoid taking cluster axis using other params
137
+ sampledColsUmapParams := sampledColsUmapConv.getColumns(datasetSpec)
138
+ sampledColsUmapPf := xsv.importFile(sampleClones.getFile("sampledClonotypes_top.csv"), "csv", sampledColsUmapParams)
139
+ outputs["sampledRowsUmap"] = pframes.exportFrame(sampledColsUmapPf)
140
+ }
141
+
142
+ ////////// UMAP //////////
143
+ // Generate input TSV with Clonotype ID and aa sequence
144
+ umapTable := columns.xsvTableBuilder()
145
+ umapTable.setAxisHeader(datasetSpec.axesSpec[1].name, "clonotypeKey")
146
+ for col in columns.getColumns("aaSequence") {
147
+ if isSingleCell {
148
+ chainLabel := col.spec.domain["pl7.app/vdj/scClonotypeChain"]
149
+ umapTable.add(col.key, {header: "aaSequence." + chainLabel})
150
+ } else {
151
+ chainLabel := col.spec.axesSpec[0].domain["pl7.app/vdj/chain"]
152
+ umapTable.add(col.key, {header: "aaSequence." + chainLabel})
153
+ }
154
+ }
155
+ umapTable = umapTable.build("tsv")
156
+
157
+ // UMAP script should go here
158
+ umapClones := exec.builder().
159
+ software(assets.importSoftware("@platforma-open/milaboratories.top-antibodies.umap:main")).
160
+ addFile("sequences.tsv", umapTable).
161
+ arg("-i").arg("sequences.tsv").
162
+ arg("-u").arg("umap.tsv").
163
+ saveFile("umap.tsv").
164
+ printErrStreamToStdout().
165
+ saveStdoutContent().
166
+ cache(24 * 60 * 60 * 1000).
167
+ run()
168
+
169
+
170
+ umapPf := xsv.importFile(umapClones.getFile("umap.tsv"), "tsv", umapConv.getColumns(datasetSpec))
171
+ outputs["umap"] = pframes.exportFrame(umapPf)
172
+
173
+ ////////// CDR3 Length Calculation //////////
174
+
175
+ cdr3SeqTable := columns.xsvTableBuilder()
176
+ cdr3SeqTable.setAxisHeader(datasetSpec.axesSpec[1].name, "clonotypeKey")
177
+
178
+ // Must deal with multiple CDR3 sequences (two for each cell in single cell data)
179
+ // Chain will be added in the header as cdr3Sequence.chain and used in python script
180
+ // Notice chain is in spec.domain for single cell data and spec.axesSpec[0].domain for bulk data
181
+
182
+ // Helper function to add chain information to the headers dynamically
183
+ chainMapping := {
184
+ "IG": { "A": "Heavy", "B": "Light" },
185
+ "TCRAB": { "A": "TRA", "B": "TRB" },
186
+ "TCRGD": { "A": "TRG", "B": "TRD" }
187
+ }
188
+
189
+ makeHeaderName := func(col, baseHeaderName, isSingleCell) {
190
+ if isSingleCell {
191
+ chain := col.spec.domain["pl7.app/vdj/scClonotypeChain"] // e.g., "A", "B"
192
+ receptor := col.spec.axesSpec[0].domain["pl7.app/vdj/receptor"] // e.g., "IG", "TCRAB", "TCRGD"
193
+ chainLabel := chainMapping[receptor][chain]
194
+ return baseHeaderName + "." + chainLabel
195
+ } else {
196
+ // For bulk, if chain info is available (e.g. IGH, IGK, IGL)
197
+ chainFromDomain := col.spec.axesSpec[0].domain["pl7.app/vdj/chain"] // e.g. "IGH", "IGK"
198
+ if chainFromDomain != undefined {
199
+ return baseHeaderName + "." + chainFromDomain
200
+ }
201
+ }
202
+ return baseHeaderName // Default header for bulk
203
+ };
204
+
205
+ // Process CDR3 sequences
206
+ cdr3Sequences := columns.getColumns("cdr3Sequences")
207
+
208
+ for col in cdr3Sequences {
209
+ headerName := makeHeaderName(col, "cdr3Sequence", isSingleCell)
210
+ cdr3SeqTable.add(col.key, {header: headerName})
211
+ }
212
+
213
+ // Process V genes
214
+ vGenes := columns.getColumns("VGenes")
215
+
216
+ for col in vGenes {
217
+ headerName := makeHeaderName(col, "vGene", isSingleCell)
218
+ cdr3SeqTable.add(col.key, {header: headerName})
219
+ }
220
+
221
+ cdr3SeqTableBuilt := cdr3SeqTable.build("tsv")
222
+
223
+ cdr3VspectratypeCmd := exec.builder().
224
+ software(assets.importSoftware("@platforma-open/milaboratories.top-antibodies.spectratype:main")).
225
+ addFile("cdr3_sequences_input.tsv", cdr3SeqTableBuilt).
226
+ arg("--input_tsv").arg("cdr3_sequences_input.tsv").
227
+ arg("--output_tsv").arg("cdr3_lengths.tsv").
228
+ saveFile("cdr3_lengths.tsv").
229
+ printErrStreamToStdout().
230
+ saveStdoutContent().
231
+ cache(24 * 60 * 60 * 1000).
232
+ run()
233
+
234
+
235
+ // For spectratype structure is:
236
+ // [chain][cdr3Length][vGene] -> count
237
+
238
+ // Get the spec for the vGene column
239
+ vGeneSpec := columns.getSpec(vGenes[0].key)
240
+
241
+ // Set up the axes for the output data
242
+ axes := [
243
+ {
244
+ column: "chain",
245
+ spec: {
246
+ name: "pl7.app/vdj/chain",
247
+ type: "String", // For axis it is type, not valueType
248
+ annotations: { "pl7.app/label": "CDR3 chain" }
249
+ }
250
+ },
251
+ {
252
+ column: "cdr3Length",
253
+ spec: {
254
+ name: "pl7.app/vdj/sequenceLength",
255
+ type: "Int",
256
+ domain: {
257
+ "pl7.app/vdj/feature": "CDR3",
258
+ "pl7.app/alphabet": "aminoacid"
259
+ },
260
+ annotations: { "pl7.app/label": "CDR3 aa Length" }
261
+ }
262
+ },
263
+ {
264
+ column: "vGene",
265
+ spec: {
266
+ name: "pl7.app/vdj/geneHit",
267
+ type: "String",
268
+ domain: vGeneSpec.domain,
269
+ annotations: {
270
+ "pl7.app/label": "Best V gene"
271
+ }
272
+ }
273
+ }
274
+
275
+ ]
276
+
277
+
278
+ spectratypeColumns := [
279
+ {
280
+ column: "count",
281
+ spec: {
282
+ name: "pl7.app/vdj/vSpectratype",
283
+ valueType: "Int",
284
+ domain: {
285
+ "pl7.app/vdj/feature": "CDR3",
286
+ "pl7.app/alphabet": "aminoacid"
287
+ },
288
+ annotations: { "pl7.app/label": "CDR3 V Spectratype" }
289
+ }
290
+ }
291
+ ]
292
+
293
+ spectratypeSpec := {
294
+ axes: axes,
295
+ columns: spectratypeColumns,
296
+ storageFormat: "Binary",
297
+ partitionKeyLength: 0
298
+ }
299
+
300
+ cdr3VspectratypePf := xsv.importFile(cdr3VspectratypeCmd.getFile("cdr3_lengths.tsv"), "tsv", spectratypeSpec)
301
+
302
+ outputs["cdr3VspectratypePf"] = pframes.exportFrame(cdr3VspectratypePf)
303
+ //ll.print("CDR3 lengths PFrame imported.")
304
+
6
305
  return {
7
- outputs: {},
306
+ outputs: outputs,
8
307
  exports: {}
9
308
  }
10
309
  })
11
-
@@ -0,0 +1,43 @@
1
+ ll := import("@platforma-sdk/workflow-tengo:ll")
2
+
3
+ getColumns := func(datasetSpec) {
4
+ return {
5
+ "axes": [
6
+ {
7
+ "column": "clonotypeKey",
8
+ "spec": datasetSpec.axesSpec[1]
9
+ }
10
+ ],
11
+ "columns": [
12
+ {
13
+ "column": "UMAP1",
14
+ "id": "umap1",
15
+ "allowNA": false,
16
+ "spec": {
17
+ "name": "pl7.app/vdj/umap1",
18
+ "valueType": "Double",
19
+ "annotations": {
20
+ "pl7.app/label": "UMAP Dim1"
21
+ }
22
+ }
23
+ },
24
+ {
25
+ "column": "UMAP2",
26
+ "id": "umap2",
27
+ "allowNA": false,
28
+ "spec": {
29
+ "name": "pl7.app/vdj/umap2",
30
+ "valueType": "Double",
31
+ "annotations": {
32
+ "pl7.app/label": "UMAP Dim2"
33
+ }
34
+ }
35
+ }],
36
+ "storageFormat": "Binary",
37
+ "partitionKeyLength": 0
38
+ }
39
+ }
40
+
41
+ export ll.toStrict({
42
+ getColumns: getColumns
43
+ })
@@ -0,0 +1,45 @@
1
+ ll := import("@platforma-sdk/workflow-tengo:ll")
2
+
3
+ getColumns := func(datasetSpec, linkerAxisSpec) {
4
+ axes := [
5
+ {
6
+ "column": "clonotypeKey",
7
+ "spec": datasetSpec.axesSpec[1]
8
+ }]
9
+
10
+ if len(linkerAxisSpec) > 0 {
11
+ for key, val in linkerAxisSpec {
12
+ axes = axes + [
13
+ {
14
+ "column": key,
15
+ "spec": val
16
+ }]
17
+ }
18
+
19
+ }
20
+ return {
21
+ "axes": axes,
22
+ "columns": [
23
+ {
24
+ "column": "top",
25
+ "id": "link",
26
+ "allowNA": false,
27
+ "spec": {
28
+ "name": "pl7.app/vdj/sampling-column",
29
+ "valueType": "Int",
30
+ "domain": {},
31
+ "annotations": {
32
+ "pl7.app/label": "Sampling column",
33
+ "pl7.app/table/visibility": "optional"
34
+ }
35
+ }
36
+ }
37
+ ],
38
+ "storageFormat": "Binary",
39
+ "partitionKeyLength": 0
40
+ }
41
+ }
42
+
43
+ export ll.toStrict({
44
+ getColumns: getColumns
45
+ })
@@ -0,0 +1,38 @@
1
+ ll := import("@platforma-sdk/workflow-tengo:ll")
2
+
3
+ // modified from sampled-cols-conv.lib.tengo
4
+
5
+ getColumns := func(datasetSpec) {
6
+ axes := [
7
+ {
8
+ "column": "clonotypeKey",
9
+ "spec": datasetSpec.axesSpec[1]
10
+ }]
11
+
12
+ return {
13
+ "axes": axes,
14
+ "columns": [
15
+ {
16
+ "column": "top",
17
+ "id": "link2", // temporal change
18
+ "allowNA": false,
19
+ "spec": {
20
+ "name": "pl7.app/vdj/sampling-column-umap",
21
+ "valueType": "Int",
22
+ "domain": {},
23
+ "annotations": {
24
+ "pl7.app/label": "Top clonotypes",
25
+ "pl7.app/table/visibility": "optional",
26
+ "pl7.app/isSubset": "true"
27
+ }
28
+ }
29
+ }
30
+ ],
31
+ "storageFormat": "Binary",
32
+ "partitionKeyLength": 0
33
+ }
34
+ }
35
+
36
+ export ll.toStrict({
37
+ getColumns: getColumns
38
+ })
package/src/wf.test.ts DELETED
@@ -1,13 +0,0 @@
1
- import { tplTest } from "@platforma-sdk/test";
2
-
3
- tplTest(
4
- 'should return a concatenated string',
5
- async ({ helper, expect }) => {
6
- const results = await helper.renderWorkflow("main", false, {
7
- name: 'World'
8
- });
9
-
10
- const tengoMessage = results.output("tengoMessage", (a) => a?.getDataAsJson<string>());
11
- expect(await tengoMessage.awaitStableValue()).eq('Hello from Tengo, World!');
12
- }
13
- );