@platforma-open/milaboratories.top-antibodies.workflow 1.8.1 → 1.9.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.
- package/.turbo/turbo-build.log +1 -1
- package/CHANGELOG.md +17 -0
- package/dist/tengo/lib/sampled-cols-conv.lib.tengo +27 -11
- package/dist/tengo/tpl/filter-and-sample.plj.gz +0 -0
- package/dist/tengo/tpl/main.plj.gz +0 -0
- package/dist/tengo/tpl/prerun.plj.gz +0 -0
- package/package.json +2 -2
- package/src/filter-and-sample.tpl.tengo +3 -2
- package/src/main.tpl.tengo +26 -26
- package/src/prerun.tpl.tengo +2 -2
- package/src/sampled-cols-conv.lib.tengo +27 -11
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
WARN Issue while reading "/home/runner/work/antibody-tcr-lead-selection/antibody-tcr-lead-selection/.npmrc". Failed to replace env in config: ${NPMJS_TOKEN}
|
|
2
2
|
|
|
3
|
-
> @platforma-open/milaboratories.top-antibodies.workflow@1.
|
|
3
|
+
> @platforma-open/milaboratories.top-antibodies.workflow@1.9.0 build /home/runner/work/antibody-tcr-lead-selection/antibody-tcr-lead-selection/workflow
|
|
4
4
|
> rm -rf dist && pl-tengo check && pl-tengo build
|
|
5
5
|
|
|
6
6
|
Processing "src/filter-and-sample.tpl.tengo"...
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,22 @@
|
|
|
1
1
|
# @platforma-open/milaboratories.top-antibodies.workflow
|
|
2
2
|
|
|
3
|
+
## 1.9.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- b499ab2: Add rank column
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- Updated dependencies [b499ab2]
|
|
12
|
+
- @platforma-open/milaboratories.top-antibodies.sample-clonotypes@1.2.0
|
|
13
|
+
|
|
14
|
+
## 1.8.2
|
|
15
|
+
|
|
16
|
+
### Patch Changes
|
|
17
|
+
|
|
18
|
+
- f25cad6: Fix slices typo in main workflow
|
|
19
|
+
|
|
3
20
|
## 1.8.1
|
|
4
21
|
|
|
5
22
|
### Patch Changes
|
|
@@ -1,14 +1,7 @@
|
|
|
1
1
|
ll := import("@platforma-sdk/workflow-tengo:ll")
|
|
2
2
|
|
|
3
|
-
getColumns := func(datasetSpec) {
|
|
4
|
-
|
|
5
|
-
axes: [
|
|
6
|
-
{
|
|
7
|
-
column: "clonotypeKey",
|
|
8
|
-
spec: datasetSpec.axesSpec[1]
|
|
9
|
-
}],
|
|
10
|
-
columns: [
|
|
11
|
-
{
|
|
3
|
+
getColumns := func(datasetSpec, addRanking) {
|
|
4
|
+
columns := [{
|
|
12
5
|
column: "top",
|
|
13
6
|
id: "link",
|
|
14
7
|
allowNA: false,
|
|
@@ -22,8 +15,31 @@ getColumns := func(datasetSpec) {
|
|
|
22
15
|
"pl7.app/isSubset": "true"
|
|
23
16
|
}
|
|
24
17
|
}
|
|
25
|
-
}
|
|
26
|
-
|
|
18
|
+
}]
|
|
19
|
+
if addRanking {
|
|
20
|
+
columns = columns + [{
|
|
21
|
+
column: "ranked_order",
|
|
22
|
+
spec: {
|
|
23
|
+
name: "pl7.app/vdj/ranking-order",
|
|
24
|
+
valueType: "Int",
|
|
25
|
+
domain: {},
|
|
26
|
+
annotations: {
|
|
27
|
+
"pl7.app/label": "Rank",
|
|
28
|
+
"pl7.app/table/visibility": "optional",
|
|
29
|
+
"pl7.app/isSubset": "true"
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}]
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
return {
|
|
37
|
+
axes: [
|
|
38
|
+
{
|
|
39
|
+
column: "clonotypeKey",
|
|
40
|
+
spec: datasetSpec.axesSpec[1]
|
|
41
|
+
}],
|
|
42
|
+
columns: columns,
|
|
27
43
|
storageFormat: "Binary",
|
|
28
44
|
partitionKeyLength: 0
|
|
29
45
|
}
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@platforma-open/milaboratories.top-antibodies.workflow",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.9.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Block Workflow",
|
|
6
6
|
"dependencies": {
|
|
7
7
|
"@platforma-sdk/workflow-tengo": "^4.9.2",
|
|
8
|
-
"@platforma-open/milaboratories.top-antibodies.sample-clonotypes": "1.
|
|
8
|
+
"@platforma-open/milaboratories.top-antibodies.sample-clonotypes": "1.2.0",
|
|
9
9
|
"@platforma-open/milaboratories.top-antibodies.spectratype": "1.4.0",
|
|
10
10
|
"@platforma-open/milaboratories.top-antibodies.umap": "1.0.3"
|
|
11
11
|
},
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Template for clonotype filtering
|
|
1
|
+
// Template for clonotype filtering and sampling
|
|
2
2
|
self := import("@platforma-sdk/workflow-tengo:tpl")
|
|
3
3
|
exec := import("@platforma-sdk/workflow-tengo:exec")
|
|
4
4
|
assets := import("@platforma-sdk/workflow-tengo:assets")
|
|
@@ -39,7 +39,7 @@ self.body(func(inputs) {
|
|
|
39
39
|
filteredClonotypesCsv := filterResult.getFile("filteredClonotypes.csv")
|
|
40
40
|
|
|
41
41
|
// Store outputs
|
|
42
|
-
sampledColsParams := sampledColsConv.getColumns(datasetSpec)
|
|
42
|
+
sampledColsParams := sampledColsConv.getColumns(datasetSpec, false) // No ranking column
|
|
43
43
|
filteredClonotypesPf := xsv.importFile(filteredClonotypesCsv, "csv", sampledColsParams,
|
|
44
44
|
{cpu: 1, mem: "16GiB"})
|
|
45
45
|
|
|
@@ -69,6 +69,7 @@ self.body(func(inputs) {
|
|
|
69
69
|
finalClonotypesCsv = sampleClones.getFile("sampledClonotypes_top.csv")
|
|
70
70
|
|
|
71
71
|
// Store outputs
|
|
72
|
+
sampledColsParams := sampledColsConv.getColumns(datasetSpec, true) // Add ranking column
|
|
72
73
|
sampledColumnsPf := xsv.importFile(finalClonotypesCsv, "csv", sampledColsParams,
|
|
73
74
|
{cpu: 1, mem: "16GiB"})
|
|
74
75
|
outputs["sampledRows"] = pframes.exportFrame(sampledColumnsPf)
|
package/src/main.tpl.tengo
CHANGED
|
@@ -4,7 +4,6 @@ exec := import("@platforma-sdk/workflow-tengo:exec")
|
|
|
4
4
|
assets:= import("@platforma-sdk/workflow-tengo:assets")
|
|
5
5
|
xsv := import("@platforma-sdk/workflow-tengo:pframes.xsv")
|
|
6
6
|
pframes := import("@platforma-sdk/workflow-tengo:pframes")
|
|
7
|
-
sampledColsConv := import(":sampled-cols-conv")
|
|
8
7
|
spectratypeConv := import(":pf-spectratype-conv")
|
|
9
8
|
vjUsageConv := import(":pf-vj-usage-conv")
|
|
10
9
|
slices := import("@platforma-sdk/workflow-tengo:slices")
|
|
@@ -88,23 +87,23 @@ wf.body(func(args) {
|
|
|
88
87
|
// Input arguments
|
|
89
88
|
columns := args.columns
|
|
90
89
|
datasetSpec := columns.getSpec(args.inputAnchor)
|
|
91
|
-
|
|
92
90
|
topClonotypes := args.topClonotypes
|
|
93
91
|
|
|
94
|
-
// Needed conditional
|
|
92
|
+
// Needed conditional variable
|
|
95
93
|
isSingleCell := datasetSpec.axesSpec[1].name == "pl7.app/vdj/scClonotypeKey"
|
|
96
94
|
|
|
97
|
-
//
|
|
95
|
+
// Output container
|
|
98
96
|
outputs := {}
|
|
99
97
|
|
|
100
|
-
//
|
|
101
|
-
// Build clonotype table
|
|
98
|
+
// Build clonotype table csv for filtering script
|
|
102
99
|
cloneTable := pframes.csvFileBuilder()
|
|
103
100
|
cloneTable.setAxisHeader(datasetSpec.axesSpec[1].name, "clonotypeKey")
|
|
104
101
|
|
|
105
|
-
// Add
|
|
106
|
-
|
|
107
|
-
|
|
102
|
+
// Add filter columns to table
|
|
103
|
+
// Filter structure {id: UI id, value: AnchoredColumnId, filter: Filter criteria, isExpanded: boolean (UI state)}
|
|
104
|
+
// AnchoredColumnId {anchorRef: PlRef, anchorName: string, column: SUniversalPColumnId (unique column id)}
|
|
105
|
+
addedAxes := [] // Keep track of axes that are added to the table to prevent duplicates
|
|
106
|
+
filterMap := {} // Map column headers to filter criteria
|
|
108
107
|
if len(args.filters) > 0 {
|
|
109
108
|
for i, filter in args.filters {
|
|
110
109
|
if filter.value != undefined {
|
|
@@ -114,14 +113,14 @@ wf.body(func(args) {
|
|
|
114
113
|
// Store reference value and filter type associated to this column
|
|
115
114
|
filterMap["Filter_" + string(i)] = filter.filter
|
|
116
115
|
|
|
117
|
-
// If column does not have main anchor axis we have to include theirs
|
|
116
|
+
// If column does not have main anchor axis we have to include theirs (columns coming from clustering blocks for example)
|
|
118
117
|
colsSpec := columns.getSpec(filter.value.column)
|
|
119
|
-
axesNames := slices.map(colsSpec.axesSpec, func (a) {
|
|
118
|
+
axesNames := slices.map(colsSpec.axesSpec, func (a) {return a.name})
|
|
120
119
|
if !slices.hasElement(axesNames, datasetSpec.axesSpec[1].name) {
|
|
121
120
|
for na, ax in colsSpec.axesSpec {
|
|
122
121
|
if ax.name != datasetSpec.axesSpec[1].name {
|
|
123
122
|
cloneTable.setAxisHeader(ax.name, "cluster_" + string(i) + string(na))
|
|
124
|
-
addedAxes =
|
|
123
|
+
addedAxes = append(addedAxes, ax.name)
|
|
125
124
|
}
|
|
126
125
|
}
|
|
127
126
|
}
|
|
@@ -134,12 +133,12 @@ wf.body(func(args) {
|
|
|
134
133
|
for i, col in args.rankingOrder {
|
|
135
134
|
cloneTable.add(columns.getColumn(col.value.column), {header: "Col" + string(i)})
|
|
136
135
|
|
|
137
|
-
// If column does not have main anchor axis we have to include theirs
|
|
136
|
+
// If column does not have main anchor axis we have to include theirs (columns coming from clustering blocks for example)
|
|
138
137
|
colsSpec := columns.getSpec(col.value.column)
|
|
139
|
-
axesNames := slices.map(colsSpec.axesSpec, func (a) {
|
|
138
|
+
axesNames := slices.map(colsSpec.axesSpec, func (a) {return a.name})
|
|
140
139
|
if !slices.hasElement(axesNames, datasetSpec.axesSpec[1].name) {
|
|
141
140
|
for na, ax in colsSpec.axesSpec {
|
|
142
|
-
if ax.name != datasetSpec.axesSpec[1].name && !slices.hasElement(addedAxes, ax.name) {
|
|
141
|
+
if ax.name != datasetSpec.axesSpec[1].name && !slices.hasElement(addedAxes, ax.name) { // Prevent duplicates
|
|
143
142
|
cloneTable.setAxisHeader(ax.name, "cluster_" + string(i) + string(na))
|
|
144
143
|
}
|
|
145
144
|
}
|
|
@@ -161,8 +160,8 @@ wf.body(func(args) {
|
|
|
161
160
|
}
|
|
162
161
|
}
|
|
163
162
|
|
|
164
|
-
//
|
|
165
|
-
linkerAxisSpec := {}
|
|
163
|
+
// Add linker columns when needed
|
|
164
|
+
linkerAxisSpec := {} // Map cluster axis names to specs. Is it needed????
|
|
166
165
|
if len(columns.getColumns("linkers")) > 0 {
|
|
167
166
|
for i, col in columns.getColumns("linkers") {
|
|
168
167
|
if datasetSpec.axesSpec[1].name == col.spec.axesSpec[1].name {
|
|
@@ -180,8 +179,8 @@ wf.body(func(args) {
|
|
|
180
179
|
cloneTable.cpu(1)
|
|
181
180
|
cloneTable = cloneTable.build()
|
|
182
181
|
|
|
183
|
-
// Use
|
|
184
|
-
|
|
182
|
+
// Use render.create to call the filtering and sampling clonotypes template
|
|
183
|
+
filterSampleResult := render.create(filterAndSampleTpl, {
|
|
185
184
|
inputAnchor: args.inputAnchor,
|
|
186
185
|
cloneTable: cloneTable,
|
|
187
186
|
rankingOrder: args.rankingOrder,
|
|
@@ -192,9 +191,9 @@ wf.body(func(args) {
|
|
|
192
191
|
topClonotypes: args.topClonotypes
|
|
193
192
|
})
|
|
194
193
|
|
|
195
|
-
// Get the filtered clonotypes P-frame and CSV from the template result
|
|
196
|
-
finalClonotypesCsv :=
|
|
197
|
-
// outputs["sampledRows"] =
|
|
194
|
+
// Get the filtered and sampled clonotypes P-frame and CSV from the template result
|
|
195
|
+
finalClonotypesCsv := filterSampleResult.output("finalClonotypesCsv", 24 * 60 * 60 * 1000)
|
|
196
|
+
// outputs["sampledRows"] = filterSampleResult.output("sampledRows", 24 * 60 * 60 * 1000)
|
|
198
197
|
|
|
199
198
|
////////// CDR3 Length Calculation //////////
|
|
200
199
|
|
|
@@ -217,15 +216,15 @@ wf.body(func(args) {
|
|
|
217
216
|
chain := col.spec.domain["pl7.app/vdj/scClonotypeChain"] // e.g., "A", "B"
|
|
218
217
|
receptor := col.spec.axesSpec[0].domain["pl7.app/vdj/receptor"] // e.g., "IG", "TCRAB", "TCRGD"
|
|
219
218
|
chainLabel := chainMapping[receptor][chain]
|
|
220
|
-
return baseHeaderName + "." + chainLabel
|
|
219
|
+
return baseHeaderName + "." + chainLabel // e.g., "cdr3Sequence.Heavy"
|
|
221
220
|
} else {
|
|
222
221
|
// For bulk, if chain info is available (e.g. IGH, IGK, IGL)
|
|
223
222
|
chainFromDomain := col.spec.axesSpec[0].domain["pl7.app/vdj/chain"] // e.g. "IGH", "IGK"
|
|
224
223
|
if chainFromDomain != undefined {
|
|
225
|
-
return baseHeaderName + "." + chainFromDomain
|
|
224
|
+
return baseHeaderName + "." + chainFromDomain // e.g., "cdr3Sequence.IGH"
|
|
226
225
|
}
|
|
227
226
|
}
|
|
228
|
-
return baseHeaderName
|
|
227
|
+
return baseHeaderName
|
|
229
228
|
};
|
|
230
229
|
|
|
231
230
|
// Process CDR3 sequences
|
|
@@ -251,6 +250,7 @@ wf.body(func(args) {
|
|
|
251
250
|
headerName := makeHeaderName(col, "jGene", isSingleCell)
|
|
252
251
|
cdr3SeqTable.add(col, {header: headerName})
|
|
253
252
|
}
|
|
253
|
+
|
|
254
254
|
cdr3SeqTable.mem("16GiB")
|
|
255
255
|
cdr3SeqTable.cpu(1)
|
|
256
256
|
cdr3SeqTableBuilt := cdr3SeqTable.build()
|
|
@@ -280,7 +280,7 @@ wf.body(func(args) {
|
|
|
280
280
|
run()
|
|
281
281
|
|
|
282
282
|
|
|
283
|
-
//
|
|
283
|
+
// Spectratype PFrame structure is [chain][cdr3Length][vGene] -> count
|
|
284
284
|
|
|
285
285
|
cdr3VspectratypePf := xsv.importFile(cdr3VspectratypeCmd.getFile("spectratype.tsv"),
|
|
286
286
|
"tsv", spectratypeConv.getColumns(),
|
package/src/prerun.tpl.tengo
CHANGED
|
@@ -182,7 +182,7 @@ wf.body(func(args) {
|
|
|
182
182
|
cloneTable = cloneTable.build()
|
|
183
183
|
|
|
184
184
|
// Use ender.create to call the filter-clonotypes template
|
|
185
|
-
|
|
185
|
+
filterSampleResult := render.create(filterAndSampleTpl, {
|
|
186
186
|
inputAnchor: args.inputAnchor,
|
|
187
187
|
cloneTable: cloneTable,
|
|
188
188
|
topClonotypes: args.topClonotypes,
|
|
@@ -194,7 +194,7 @@ wf.body(func(args) {
|
|
|
194
194
|
})
|
|
195
195
|
|
|
196
196
|
// Get the filtered clonotypes from the template result
|
|
197
|
-
outputs["sampledRows"] =
|
|
197
|
+
outputs["sampledRows"] = filterSampleResult.output("sampledRows", 24 * 60 * 60 * 1000)
|
|
198
198
|
}
|
|
199
199
|
|
|
200
200
|
return {
|
|
@@ -1,14 +1,7 @@
|
|
|
1
1
|
ll := import("@platforma-sdk/workflow-tengo:ll")
|
|
2
2
|
|
|
3
|
-
getColumns := func(datasetSpec) {
|
|
4
|
-
|
|
5
|
-
axes: [
|
|
6
|
-
{
|
|
7
|
-
column: "clonotypeKey",
|
|
8
|
-
spec: datasetSpec.axesSpec[1]
|
|
9
|
-
}],
|
|
10
|
-
columns: [
|
|
11
|
-
{
|
|
3
|
+
getColumns := func(datasetSpec, addRanking) {
|
|
4
|
+
columns := [{
|
|
12
5
|
column: "top",
|
|
13
6
|
id: "link",
|
|
14
7
|
allowNA: false,
|
|
@@ -22,8 +15,31 @@ getColumns := func(datasetSpec) {
|
|
|
22
15
|
"pl7.app/isSubset": "true"
|
|
23
16
|
}
|
|
24
17
|
}
|
|
25
|
-
}
|
|
26
|
-
|
|
18
|
+
}]
|
|
19
|
+
if addRanking {
|
|
20
|
+
columns = columns + [{
|
|
21
|
+
column: "ranked_order",
|
|
22
|
+
spec: {
|
|
23
|
+
name: "pl7.app/vdj/ranking-order",
|
|
24
|
+
valueType: "Int",
|
|
25
|
+
domain: {},
|
|
26
|
+
annotations: {
|
|
27
|
+
"pl7.app/label": "Rank",
|
|
28
|
+
"pl7.app/table/visibility": "optional",
|
|
29
|
+
"pl7.app/isSubset": "true"
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}]
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
return {
|
|
37
|
+
axes: [
|
|
38
|
+
{
|
|
39
|
+
column: "clonotypeKey",
|
|
40
|
+
spec: datasetSpec.axesSpec[1]
|
|
41
|
+
}],
|
|
42
|
+
columns: columns,
|
|
27
43
|
storageFormat: "Binary",
|
|
28
44
|
partitionKeyLength: 0
|
|
29
45
|
}
|