@platforma-open/milaboratories.top-antibodies.workflow 3.0.0 → 4.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.
@@ -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@3.0.0 build /home/runner/work/antibody-tcr-lead-selection/antibody-tcr-lead-selection/workflow
3
+ > @platforma-open/milaboratories.top-antibodies.workflow@4.0.0 build /home/runner/work/antibody-tcr-lead-selection/antibody-tcr-lead-selection/workflow
4
4
  > shx rm -rf dist && pl-tengo check && pl-tengo build
5
5
 
6
6
  Processing "src/assembling-fasta.tpl.tengo"...
package/CHANGELOG.md CHANGED
@@ -1,5 +1,23 @@
1
1
  # @platforma-open/milaboratories.top-antibodies.workflow
2
2
 
3
+ ## 4.0.0
4
+
5
+ ### Major Changes
6
+
7
+ - 1c1c7c1: Support peptides
8
+
9
+ ## 3.0.1
10
+
11
+ ### Patch Changes
12
+
13
+ - 3e9c9ef: bump sdk for fix table query
14
+ - Updated dependencies [3e9c9ef]
15
+ - @platforma-open/milaboratories.top-antibodies.anarci-kabat@1.4.3
16
+ - @platforma-open/milaboratories.top-antibodies.assembling-fasta@1.3.2
17
+ - @platforma-open/milaboratories.top-antibodies.sample-clonotypes@2.1.2
18
+ - @platforma-open/milaboratories.top-antibodies.spectratype@1.8.3
19
+ - @platforma-open/milaboratories.top-antibodies.umap@1.2.3
20
+
3
21
  ## 3.0.0
4
22
 
5
23
  ### Major Changes
@@ -6,7 +6,7 @@ getColumns := func(datasetSpec, addRanking, addInVivoScore) {
6
6
  id: "link",
7
7
  allowNA: false,
8
8
  spec: {
9
- name: "pl7.app/vdj/lead-selection",
9
+ name: "pl7.app/lead-selection",
10
10
  valueType: "Int",
11
11
  domain: {},
12
12
  annotations: {
@@ -21,7 +21,7 @@ getColumns := func(datasetSpec, addRanking, addInVivoScore) {
21
21
  columns = columns + [{
22
22
  column: "ranked_order",
23
23
  spec: {
24
- name: "pl7.app/vdj/ranking-order",
24
+ name: "pl7.app/ranking-order",
25
25
  valueType: "Int",
26
26
  domain: {},
27
27
  annotations: {
@@ -18,7 +18,7 @@ getColumns := func(datasetSpec, filterMap, rankingMap, diversificationColumn, to
18
18
  id: "link",
19
19
  allowNA: false,
20
20
  spec: {
21
- name: "pl7.app/vdj/lead-selection",
21
+ name: "pl7.app/lead-selection",
22
22
  valueType: "Int",
23
23
  domain: domain,
24
24
  annotations: {
@@ -61,7 +61,7 @@ findMatchingLinkerIndex := func(colsSpec, linkerColumns) {
61
61
 
62
62
  rankingClusterIdAxis := undefined
63
63
  for axis in colsSpec.axesSpec {
64
- if axis.name == "pl7.app/vdj/clusterId" {
64
+ if axis.name == "pl7.app/clusterId" {
65
65
  rankingClusterIdAxis = axis
66
66
  break
67
67
  }
@@ -76,7 +76,7 @@ findMatchingLinkerIndex := func(colsSpec, linkerColumns) {
76
76
 
77
77
  linkerClusterIdAxis := undefined
78
78
  for axis in linkerCol.spec.axesSpec {
79
- if axis.name == "pl7.app/vdj/clusterId" {
79
+ if axis.name == "pl7.app/clusterId" {
80
80
  linkerClusterIdAxis = axis
81
81
  break
82
82
  }
@@ -195,7 +195,7 @@ resolveClusterColumnHeader := func(args, columns, sortedLinkers) {
195
195
 
196
196
  selectedClusterIdAxis := undefined
197
197
  for axis in selectedLinkerSpec.axesSpec {
198
- if axis.name == "pl7.app/vdj/clusterId" {
198
+ if axis.name == "pl7.app/clusterId" {
199
199
  selectedClusterIdAxis = axis
200
200
  break
201
201
  }
@@ -209,7 +209,7 @@ resolveClusterColumnHeader := func(args, columns, sortedLinkers) {
209
209
  for linkerIdx, col in sortedLinkers {
210
210
 
211
211
  for axis in col.spec.axesSpec {
212
- if axis.name == "pl7.app/vdj/clusterId" {
212
+ if axis.name == "pl7.app/clusterId" {
213
213
 
214
214
  if clusterAxisDomainsMatch(selectedClusterIdAxis, axis) {
215
215
  return "clusterAxis_" + string(linkerIdx) + "_0"
@@ -409,7 +409,7 @@ initializeCloneTable := func(pframes, columns, args, datasetSpec) {
409
409
  addedCols = true
410
410
  }
411
411
 
412
- if !is_undefined(clusterIdAxis) && clusterIdAxis.name == "pl7.app/vdj/clusterId" {
412
+ if !is_undefined(clusterIdAxis) && clusterIdAxis.name == "pl7.app/clusterId" {
413
413
  linkerClusterIdAxesWithIdx = append(linkerClusterIdAxesWithIdx, {
414
414
  axis: clusterIdAxis,
415
415
  linkerIdx: linkerIdx
@@ -423,7 +423,7 @@ initializeCloneTable := func(pframes, columns, args, datasetSpec) {
423
423
 
424
424
  clusterSizeClusterIdAxis := undefined
425
425
  for axis in col.spec.axesSpec {
426
- if axis.name == "pl7.app/vdj/clusterId" {
426
+ if axis.name == "pl7.app/clusterId" {
427
427
  clusterSizeClusterIdAxis = axis
428
428
  break
429
429
  }
Binary file
package/package.json CHANGED
@@ -1,19 +1,19 @@
1
1
  {
2
2
  "name": "@platforma-open/milaboratories.top-antibodies.workflow",
3
- "version": "3.0.0",
3
+ "version": "4.0.0",
4
4
  "type": "module",
5
5
  "description": "Block Workflow",
6
6
  "dependencies": {
7
- "@platforma-sdk/workflow-tengo": "5.13.1",
7
+ "@platforma-sdk/workflow-tengo": "5.20.0",
8
8
  "@platforma-open/milaboratories.software-anarci": "^0.0.3",
9
- "@platforma-open/milaboratories.top-antibodies.sample-clonotypes": "2.1.1",
10
- "@platforma-open/milaboratories.top-antibodies.umap": "1.2.2",
11
- "@platforma-open/milaboratories.top-antibodies.spectratype": "1.8.2",
12
- "@platforma-open/milaboratories.top-antibodies.assembling-fasta": "1.3.1",
13
- "@platforma-open/milaboratories.top-antibodies.anarci-kabat": "1.4.2"
9
+ "@platforma-open/milaboratories.top-antibodies.sample-clonotypes": "2.1.2",
10
+ "@platforma-open/milaboratories.top-antibodies.assembling-fasta": "1.3.2",
11
+ "@platforma-open/milaboratories.top-antibodies.anarci-kabat": "1.4.3",
12
+ "@platforma-open/milaboratories.top-antibodies.spectratype": "1.8.3",
13
+ "@platforma-open/milaboratories.top-antibodies.umap": "1.2.3"
14
14
  },
15
15
  "devDependencies": {
16
- "@platforma-sdk/tengo-builder": "2.5.8"
16
+ "@platforma-sdk/tengo-builder": "2.5.20"
17
17
  },
18
18
  "scripts": {
19
19
  "build": "shx rm -rf dist && pl-tengo check && pl-tengo build",
@@ -134,6 +134,7 @@ wf.body(func(args) {
134
134
 
135
135
  // Needed conditional variable
136
136
  isSingleCell := datasetSpec.axesSpec[1].name == "pl7.app/vdj/scClonotypeKey"
137
+ isPeptide := datasetSpec.axesSpec[1].name == "pl7.app/variantKey"
137
138
 
138
139
  ////////// Clonotype Filtering //////////
139
140
  // Initialize and build clone table with all columns
@@ -177,76 +178,79 @@ wf.body(func(args) {
177
178
  // Export only the sampling column for downstream (built inside sub-template to avoid hang)
178
179
  exports["sampledColumnsPf"] = filterSampleResult.output("sampledColumnsExport", 24 * 60 * 60 * 1000)
179
180
 
180
- ////////// CDR3 Length Calculation //////////
181
- // Initialize and build CDR3 sequence table
182
- cdr3SeqTableBuilt := utils.initializeCdr3SeqTable(pframes, columns, datasetSpec, isSingleCell)
181
+ // CDR3 spectratype, V/J gene usage, and Kabat numbering are VDJ-only — skip for peptide inputs.
182
+ if !isPeptide {
183
+ ////////// CDR3 Length Calculation //////////
184
+ // Initialize and build CDR3 sequence table
185
+ cdr3SeqTableBuilt := utils.initializeCdr3SeqTable(pframes, columns, datasetSpec, isSingleCell)
183
186
 
184
- cdr3VspectratypeCmd := exec.builder().
185
- software(assets.importSoftware("@platforma-open/milaboratories.top-antibodies.spectratype:main")).
186
- mem("16GiB").
187
- cpu(1).
188
- addFile("cdr3_sequences_input.parquet", cdr3SeqTableBuilt).
189
- arg("--input_parquet").arg("cdr3_sequences_input.parquet").
190
- arg("--spectratype_tsv").arg("spectratype.tsv").
191
- arg("--vj_usage_tsv").arg("vj_usage.tsv") // no dot here
187
+ cdr3VspectratypeCmd := exec.builder().
188
+ software(assets.importSoftware("@platforma-open/milaboratories.top-antibodies.spectratype:main")).
189
+ mem("16GiB").
190
+ cpu(1).
191
+ addFile("cdr3_sequences_input.parquet", cdr3SeqTableBuilt).
192
+ arg("--input_parquet").arg("cdr3_sequences_input.parquet").
193
+ arg("--spectratype_tsv").arg("spectratype.tsv").
194
+ arg("--vj_usage_tsv").arg("vj_usage.tsv") // no dot here
192
195
 
193
- // Add top clonotypes argument and file to the builder if provided
194
- if finalClonotypes != undefined {
195
- cdr3VspectratypeCmd = cdr3VspectratypeCmd.
196
- arg("--final-clonotypes").arg("finalClonotypes.parquet").
197
- addFile("finalClonotypes.parquet", finalClonotypes)
198
- }
196
+ // Add top clonotypes argument and file to the builder if provided
197
+ if finalClonotypes != undefined {
198
+ cdr3VspectratypeCmd = cdr3VspectratypeCmd.
199
+ arg("--final-clonotypes").arg("finalClonotypes.parquet").
200
+ addFile("finalClonotypes.parquet", finalClonotypes)
201
+ }
199
202
 
200
- cdr3VspectratypeCmd = cdr3VspectratypeCmd. // continue building the command
201
- saveFile("spectratype.tsv").
202
- saveFile("vj_usage.tsv").
203
- printErrStreamToStdout().
204
- cache(24 * 60 * 60 * 1000).
205
- run()
203
+ cdr3VspectratypeCmd = cdr3VspectratypeCmd. // continue building the command
204
+ saveFile("spectratype.tsv").
205
+ saveFile("vj_usage.tsv").
206
+ printErrStreamToStdout().
207
+ cache(24 * 60 * 60 * 1000).
208
+ run()
206
209
 
207
210
 
208
- // Spectratype PFrame structure is [chain][cdr3Length][vGene] -> count
211
+ // Spectratype PFrame structure is [chain][cdr3Length][vGene] -> count
209
212
 
210
- cdr3VspectratypePf := xsv.importFile(cdr3VspectratypeCmd.getFile("spectratype.tsv"),
211
- "tsv", spectratypeConv.getColumns(),
212
- {cpu: 1, mem: "16GiB"})
213
- outputs["cdr3VspectratypePf"] = pframes.exportFrame(cdr3VspectratypePf)
213
+ cdr3VspectratypePf := xsv.importFile(cdr3VspectratypeCmd.getFile("spectratype.tsv"),
214
+ "tsv", spectratypeConv.getColumns(),
215
+ {cpu: 1, mem: "16GiB"})
216
+ outputs["cdr3VspectratypePf"] = pframes.exportFrame(cdr3VspectratypePf)
214
217
 
215
- // For vjUsage structure is [chain][vGene][jGene] -> count
216
- vjUsagePf := xsv.importFile(cdr3VspectratypeCmd.getFile("vj_usage.tsv"),
217
- "tsv", vjUsageConv.getColumns(),
218
- {cpu: 1, mem: "16GiB"})
219
- outputs["vjUsagePf"] = pframes.exportFrame(vjUsagePf)
218
+ // For vjUsage structure is [chain][vGene][jGene] -> count
219
+ vjUsagePf := xsv.importFile(cdr3VspectratypeCmd.getFile("vj_usage.tsv"),
220
+ "tsv", vjUsageConv.getColumns(),
221
+ {cpu: 1, mem: "16GiB"})
222
+ outputs["vjUsagePf"] = pframes.exportFrame(vjUsagePf)
220
223
 
221
- if args.kabatNumbering == true {
222
- ////////// Assembling AA sequences //////////
223
- // Initialize and build assembling sequence table
224
- assemInit := utils.initializeAssemSeqTable(pframes, columns, datasetSpec, isSingleCell)
225
- assemSeqTableBuilt := assemInit.assemSeqTable
226
- bulkChain := assemInit.bulkChain
227
- seqCols := assemInit.seqCols
224
+ if args.kabatNumbering == true {
225
+ ////////// Assembling AA sequences //////////
226
+ // Initialize and build assembling sequence table
227
+ assemInit := utils.initializeAssemSeqTable(pframes, columns, datasetSpec, isSingleCell)
228
+ assemSeqTableBuilt := assemInit.assemSeqTable
229
+ bulkChain := assemInit.bulkChain
230
+ seqCols := assemInit.seqCols
228
231
 
229
- // Convert assembling feature sequences to FASTA via sub-template
230
- assemFastaTpl := assets.importTemplate(":assembling-fasta")
231
- assem := render.create(assemFastaTpl, {
232
- inputTsv: assemSeqTableBuilt,
233
- keyColumn: "clonotypeKey",
234
- finalClonotypes: finalClonotypes,
235
- isSingleCell: isSingleCell,
236
- bulkChain: bulkChain
237
- })
238
- //outputs["assemblingAnarci"] = assem.output("anarci", 24 * 60 * 60 * 1000)
239
- kabatFile := assem.output("kabat", 24 * 60 * 60 * 1000)
240
- // Derive feature name from assembling feature columns (prefer first column's feature)
241
- featName := ""
242
- if len(seqCols) > 0 {
243
- f := seqCols[0].spec.domain["pl7.app/vdj/feature"]
244
- if f != undefined { featName = f }
232
+ // Convert assembling feature sequences to FASTA via sub-template
233
+ assemFastaTpl := assets.importTemplate(":assembling-fasta")
234
+ assem := render.create(assemFastaTpl, {
235
+ inputTsv: assemSeqTableBuilt,
236
+ keyColumn: "clonotypeKey",
237
+ finalClonotypes: finalClonotypes,
238
+ isSingleCell: isSingleCell,
239
+ bulkChain: bulkChain
240
+ })
241
+ //outputs["assemblingAnarci"] = assem.output("anarci", 24 * 60 * 60 * 1000)
242
+ kabatFile := assem.output("kabat", 24 * 60 * 60 * 1000)
243
+ // Derive feature name from assembling feature columns (prefer first column's feature)
244
+ featName := ""
245
+ if len(seqCols) > 0 {
246
+ f := seqCols[0].spec.domain["pl7.app/vdj/feature"]
247
+ if f != undefined { featName = f }
248
+ }
249
+ // Convert kabat.tsv to PFrame with proper specs (bulk: select heavy/light)
250
+ kabatPf := xsv.importFile(kabatFile, "tsv", kabatConv.getColumns(datasetSpec, featName, bulkChain), {cpu: 1, mem: "8GiB"})
251
+ outputs["assemblingKabatPf"] = pframes.exportFrame(kabatPf)
252
+ outputs["kabatStatsContent"] = assem.output("kabatStats")
245
253
  }
246
- // Convert kabat.tsv to PFrame with proper specs (bulk: select heavy/light)
247
- kabatPf := xsv.importFile(kabatFile, "tsv", kabatConv.getColumns(datasetSpec, featName, bulkChain), {cpu: 1, mem: "8GiB"})
248
- outputs["assemblingKabatPf"] = pframes.exportFrame(kabatPf)
249
- outputs["kabatStatsContent"] = assem.output("kabatStats")
250
254
  }
251
255
  }
252
256
  }
@@ -6,7 +6,7 @@ getColumns := func(datasetSpec, addRanking, addInVivoScore) {
6
6
  id: "link",
7
7
  allowNA: false,
8
8
  spec: {
9
- name: "pl7.app/vdj/lead-selection",
9
+ name: "pl7.app/lead-selection",
10
10
  valueType: "Int",
11
11
  domain: {},
12
12
  annotations: {
@@ -21,7 +21,7 @@ getColumns := func(datasetSpec, addRanking, addInVivoScore) {
21
21
  columns = columns + [{
22
22
  column: "ranked_order",
23
23
  spec: {
24
- name: "pl7.app/vdj/ranking-order",
24
+ name: "pl7.app/ranking-order",
25
25
  valueType: "Int",
26
26
  domain: {},
27
27
  annotations: {
@@ -18,7 +18,7 @@ getColumns := func(datasetSpec, filterMap, rankingMap, diversificationColumn, to
18
18
  id: "link",
19
19
  allowNA: false,
20
20
  spec: {
21
- name: "pl7.app/vdj/lead-selection",
21
+ name: "pl7.app/lead-selection",
22
22
  valueType: "Int",
23
23
  domain: domain,
24
24
  annotations: {
@@ -61,7 +61,7 @@ findMatchingLinkerIndex := func(colsSpec, linkerColumns) {
61
61
  // Find the clusterId axis in the ranking column
62
62
  rankingClusterIdAxis := undefined
63
63
  for axis in colsSpec.axesSpec {
64
- if axis.name == "pl7.app/vdj/clusterId" {
64
+ if axis.name == "pl7.app/clusterId" {
65
65
  rankingClusterIdAxis = axis
66
66
  break
67
67
  }
@@ -76,7 +76,7 @@ findMatchingLinkerIndex := func(colsSpec, linkerColumns) {
76
76
  // Get the clusterId axis from the linker column
77
77
  linkerClusterIdAxis := undefined
78
78
  for axis in linkerCol.spec.axesSpec {
79
- if axis.name == "pl7.app/vdj/clusterId" {
79
+ if axis.name == "pl7.app/clusterId" {
80
80
  linkerClusterIdAxis = axis
81
81
  break
82
82
  }
@@ -195,7 +195,7 @@ resolveClusterColumnHeader := func(args, columns, sortedLinkers) {
195
195
  // Find the clusterId axis in the selected linker
196
196
  selectedClusterIdAxis := undefined
197
197
  for axis in selectedLinkerSpec.axesSpec {
198
- if axis.name == "pl7.app/vdj/clusterId" {
198
+ if axis.name == "pl7.app/clusterId" {
199
199
  selectedClusterIdAxis = axis
200
200
  break
201
201
  }
@@ -209,7 +209,7 @@ resolveClusterColumnHeader := func(args, columns, sortedLinkers) {
209
209
  for linkerIdx, col in sortedLinkers {
210
210
  // Get the clusterId axis from this linker
211
211
  for axis in col.spec.axesSpec {
212
- if axis.name == "pl7.app/vdj/clusterId" {
212
+ if axis.name == "pl7.app/clusterId" {
213
213
  // Use clusterAxisDomainsMatch for proper domain comparison
214
214
  if clusterAxisDomainsMatch(selectedClusterIdAxis, axis) {
215
215
  return "clusterAxis_" + string(linkerIdx) + "_0"
@@ -409,7 +409,7 @@ initializeCloneTable := func(pframes, columns, args, datasetSpec) {
409
409
  addedCols = true
410
410
  }
411
411
  // Collect clusterId axes from linker columns to match cluster size columns
412
- if !is_undefined(clusterIdAxis) && clusterIdAxis.name == "pl7.app/vdj/clusterId" {
412
+ if !is_undefined(clusterIdAxis) && clusterIdAxis.name == "pl7.app/clusterId" {
413
413
  linkerClusterIdAxesWithIdx = append(linkerClusterIdAxesWithIdx, {
414
414
  axis: clusterIdAxis,
415
415
  linkerIdx: linkerIdx
@@ -423,7 +423,7 @@ initializeCloneTable := func(pframes, columns, args, datasetSpec) {
423
423
  // Find the clusterId axis in this cluster size column
424
424
  clusterSizeClusterIdAxis := undefined
425
425
  for axis in col.spec.axesSpec {
426
- if axis.name == "pl7.app/vdj/clusterId" {
426
+ if axis.name == "pl7.app/clusterId" {
427
427
  clusterSizeClusterIdAxis = axis
428
428
  break
429
429
  }