@platforma-open/milaboratories.top-antibodies.workflow 4.0.1 → 4.0.2

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@4.0.1 build /home/runner/work/antibody-tcr-lead-selection/antibody-tcr-lead-selection/workflow
3
+ > @platforma-open/milaboratories.top-antibodies.workflow@4.0.2 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,13 @@
1
1
  # @platforma-open/milaboratories.top-antibodies.workflow
2
2
 
3
+ ## 4.0.2
4
+
5
+ ### Patch Changes
6
+
7
+ - 2a2533d: Fix minor issues
8
+ - 6042e4a: Minor fix
9
+ - 461999c: Fix minor issues
10
+
3
11
  ## 4.0.1
4
12
 
5
13
  ### Patch Changes
@@ -1,5 +1,6 @@
1
1
 
2
2
 
3
+ ll := import("@platforma-sdk/workflow-tengo:ll")
3
4
  slices := import("@platforma-sdk/workflow-tengo:slices")
4
5
  json := import("json")
5
6
 
@@ -466,11 +467,18 @@ initializeCloneTable := func(pframes, columns, args, datasetSpec) {
466
467
  }
467
468
 
468
469
 
470
+
469
471
  if !addedCols {
470
472
  cdr3Sequences := columns.getColumns("cdr3Sequences")
471
473
  if len(cdr3Sequences) > 0 {
472
- cloneTable.add(cdr3Sequences[0], {header: "cdr3_fallback"})
474
+ cloneTable.add(cdr3Sequences[0], {header: "sequence_fallback"})
473
475
  addedCols = true
476
+ } else {
477
+ peptideMainSeqs := columns.getColumns("peptideMainSeqs")
478
+ if len(peptideMainSeqs) > 0 {
479
+ cloneTable.add(peptideMainSeqs[0], {header: "sequence_fallback"})
480
+ addedCols = true
481
+ }
474
482
  }
475
483
  }
476
484
 
@@ -601,11 +609,28 @@ detectBulkChain := func(seqCols) {
601
609
 
602
610
 
603
611
 
604
- initializeAssemSeqTable := func(pframes, columns, datasetSpec, isSingleCell) {
612
+
613
+ initializeAssemSeqTable := func(pframes, columns, datasetSpec, isSingleCell, isScFv) {
605
614
  assemSeqTable := pframes.parquetFileBuilder()
606
615
  assemSeqTable.setAxisHeader(datasetSpec.axesSpec[1].name, "clonotypeKey")
607
616
 
608
- seqCols := columns.getColumns("assemblingAaSeqs")
617
+ seqCols := undefined
618
+ if isScFv {
619
+ allowedFeatures := { "VDJRegion": true, "VDJRegionInFrame": true }
620
+ byChain := {}
621
+ for col in columns.getColumns("scFvPerChainSeqs") {
622
+ if is_undefined(allowedFeatures[col.spec.domain["pl7.app/vdj/feature"]]) { continue }
623
+ if col.spec.domain["pl7.app/vdj/scClonotypeChain/index"] != "primary" { continue }
624
+ sc := col.spec.domain["pl7.app/vdj/scClonotypeChain"]
625
+ if sc != "A" && sc != "B" { continue }
626
+ if is_undefined(byChain[sc]) { byChain[sc] = col }
627
+ }
628
+ seqCols = []
629
+ for _, c in byChain { seqCols = append(seqCols, c) }
630
+ } else {
631
+ seqCols = columns.getColumns("assemblingAaSeqs")
632
+ }
633
+
609
634
  for col in seqCols {
610
635
  headerName := makeHeaderName(col, "assemblingFeature", isSingleCell)
611
636
  assemSeqTable.add(col, {header: headerName})
@@ -613,7 +638,7 @@ initializeAssemSeqTable := func(pframes, columns, datasetSpec, isSingleCell) {
613
638
 
614
639
  assemSeqTable.mem("16GiB")
615
640
  assemSeqTable.cpu(1)
616
-
641
+
617
642
 
618
643
  bulkChain := undefined
619
644
  if !isSingleCell {
Binary file
package/package.json CHANGED
@@ -1,16 +1,16 @@
1
1
  {
2
2
  "name": "@platforma-open/milaboratories.top-antibodies.workflow",
3
- "version": "4.0.1",
3
+ "version": "4.0.2",
4
4
  "type": "module",
5
5
  "description": "Block Workflow",
6
6
  "dependencies": {
7
7
  "@platforma-sdk/workflow-tengo": "5.20.0",
8
8
  "@platforma-open/milaboratories.software-anarci": "^0.0.3",
9
9
  "@platforma-open/milaboratories.top-antibodies.sample-clonotypes": "2.1.2",
10
- "@platforma-open/milaboratories.top-antibodies.assembling-fasta": "1.3.2",
10
+ "@platforma-open/milaboratories.top-antibodies.spectratype": "1.8.3",
11
11
  "@platforma-open/milaboratories.top-antibodies.umap": "1.2.3",
12
12
  "@platforma-open/milaboratories.top-antibodies.anarci-kabat": "1.4.3",
13
- "@platforma-open/milaboratories.top-antibodies.spectratype": "1.8.3"
13
+ "@platforma-open/milaboratories.top-antibodies.assembling-fasta": "1.3.2"
14
14
  },
15
15
  "devDependencies": {
16
16
  "@platforma-sdk/tengo-builder": "2.5.20"
@@ -111,12 +111,37 @@ wf.prepare(func(args){
111
111
  }
112
112
  }, "JGenes")
113
113
 
114
- // Add assembling feature aminoacid sequences (bulk, sc, scFv)
114
+ // Add assembling feature aminoacid sequences (bulk, sc).
115
115
  bundleBuilder.addMulti({
116
116
  axes: [{ anchor: "main", idx: 1 }], // Clonotype axis
117
+ name: "pl7.app/vdj/sequence",
117
118
  annotations: { "pl7.app/vdj/isAssemblingFeature": "true" },
118
119
  domain: { "pl7.app/alphabet": "aminoacid" }
119
120
  }, "assemblingAaSeqs")
121
+
122
+ // Detect scFv mode by presence of the combined construct column.
123
+ bundleBuilder.addMulti({
124
+ axes: [{ anchor: "main", idx: 1 }],
125
+ name: "pl7.app/vdj/scFv-sequence"
126
+ }, "scFvDetect")
127
+
128
+ // Per-chain VDJRegion AA sequences for ANARCI/Kabat in scFv mode.
129
+ bundleBuilder.addMulti({
130
+ axes: [{ anchor: "main", idx: 1 }],
131
+ name: "pl7.app/vdj/sequence",
132
+ domain: { "pl7.app/alphabet": "aminoacid" }
133
+ }, "scFvPerChainSeqs")
134
+
135
+ // Peptide main sequence — single-axis column on variantKey, used as
136
+ // modality-aware fallback when no filter/ranking columns load.
137
+ bundleBuilder.addMulti({
138
+ axes: [{ anchor: "main", idx: 1 }],
139
+ annotations: {
140
+ "pl7.app/isAssemblingFeature": "true",
141
+ "pl7.app/isMainSequence": "true"
142
+ },
143
+ domain: { "pl7.app/alphabet": "aminoacid" }
144
+ }, "peptideMainSeqs")
120
145
 
121
146
  return {
122
147
  columns: bundleBuilder.build()
@@ -226,7 +251,8 @@ wf.body(func(args) {
226
251
  if args.kabatNumbering == true {
227
252
  ////////// Assembling AA sequences //////////
228
253
  // Initialize and build assembling sequence table
229
- assemInit := utils.initializeAssemSeqTable(pframes, columns, datasetSpec, isSingleCell)
254
+ isScFv := len(columns.getColumns("scFvDetect")) > 0
255
+ assemInit := utils.initializeAssemSeqTable(pframes, columns, datasetSpec, isSingleCell, isScFv)
230
256
  assemSeqTableBuilt := assemInit.assemSeqTable
231
257
  bulkChain := assemInit.bulkChain
232
258
  seqCols := assemInit.seqCols
@@ -1,5 +1,6 @@
1
1
  // Utility functions for antibody-tcr-lead-selection workflow
2
2
 
3
+ ll := import("@platforma-sdk/workflow-tengo:ll")
3
4
  slices := import("@platforma-sdk/workflow-tengo:slices")
4
5
  json := import("json")
5
6
 
@@ -465,12 +466,19 @@ initializeCloneTable := func(pframes, columns, args, datasetSpec) {
465
466
  }
466
467
  }
467
468
 
468
- // Fallback: if no columns added, add at least one CDR3 sequence column
469
+ // Fallback: if no columns added, add a single-axis trunk-keyed sequence
470
+ // column. Try VDJ CDR3 first
469
471
  if !addedCols {
470
472
  cdr3Sequences := columns.getColumns("cdr3Sequences")
471
473
  if len(cdr3Sequences) > 0 {
472
- cloneTable.add(cdr3Sequences[0], {header: "cdr3_fallback"})
474
+ cloneTable.add(cdr3Sequences[0], {header: "sequence_fallback"})
473
475
  addedCols = true
476
+ } else {
477
+ peptideMainSeqs := columns.getColumns("peptideMainSeqs")
478
+ if len(peptideMainSeqs) > 0 {
479
+ cloneTable.add(peptideMainSeqs[0], {header: "sequence_fallback"})
480
+ addedCols = true
481
+ }
474
482
  }
475
483
  }
476
484
 
@@ -594,18 +602,35 @@ detectBulkChain := func(seqCols) {
594
602
 
595
603
  /**
596
604
  * Initializes and builds assembling sequence table with assembling AA sequences.
597
- *
605
+
598
606
  * @param pframes - PFrames import
599
607
  * @param columns - PBundle containing all columns
600
608
  * @param datasetSpec - Dataset specification with axes
601
609
  * @param isSingleCell - Whether the data is single cell
610
+ * @param isScFv - Whether the input is scFv data
602
611
  * @return Map with keys: assemSeqTable (built table), bulkChain, seqCols
603
612
  */
604
- initializeAssemSeqTable := func(pframes, columns, datasetSpec, isSingleCell) {
613
+ initializeAssemSeqTable := func(pframes, columns, datasetSpec, isSingleCell, isScFv) {
605
614
  assemSeqTable := pframes.parquetFileBuilder()
606
615
  assemSeqTable.setAxisHeader(datasetSpec.axesSpec[1].name, "clonotypeKey")
607
616
 
608
- seqCols := columns.getColumns("assemblingAaSeqs")
617
+ seqCols := undefined
618
+ if isScFv {
619
+ allowedFeatures := { "VDJRegion": true, "VDJRegionInFrame": true }
620
+ byChain := {}
621
+ for col in columns.getColumns("scFvPerChainSeqs") {
622
+ if is_undefined(allowedFeatures[col.spec.domain["pl7.app/vdj/feature"]]) { continue }
623
+ if col.spec.domain["pl7.app/vdj/scClonotypeChain/index"] != "primary" { continue }
624
+ sc := col.spec.domain["pl7.app/vdj/scClonotypeChain"]
625
+ if sc != "A" && sc != "B" { continue }
626
+ if is_undefined(byChain[sc]) { byChain[sc] = col }
627
+ }
628
+ seqCols = []
629
+ for _, c in byChain { seqCols = append(seqCols, c) }
630
+ } else {
631
+ seqCols = columns.getColumns("assemblingAaSeqs")
632
+ }
633
+
609
634
  for col in seqCols {
610
635
  headerName := makeHeaderName(col, "assemblingFeature", isSingleCell)
611
636
  assemSeqTable.add(col, {header: headerName})
@@ -613,7 +638,7 @@ initializeAssemSeqTable := func(pframes, columns, datasetSpec, isSingleCell) {
613
638
 
614
639
  assemSeqTable.mem("16GiB")
615
640
  assemSeqTable.cpu(1)
616
-
641
+
617
642
  // Detect bulk chain if needed
618
643
  bulkChain := undefined
619
644
  if !isSingleCell {