@platforma-open/milaboratories.top-antibodies.workflow 4.1.2 → 4.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,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.1.2 build /home/runner/work/antibody-tcr-lead-selection/antibody-tcr-lead-selection/workflow
3
+ > @platforma-open/milaboratories.top-antibodies.workflow@4.2.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,11 @@
1
1
  # @platforma-open/milaboratories.top-antibodies.workflow
2
2
 
3
+ ## 4.2.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 8edddd1: Add dataset selector with optional filter dropdown. Replaces the plain dataset dropdown with `PlDatasetSelector`, and inner-joins the selected filter column into the clone table so it narrows every downstream stage (final clonotypes, spectratype, Kabat).
8
+
3
9
  ## 4.1.2
4
10
 
5
11
  ### Patch Changes
@@ -239,20 +239,32 @@ resolveClusterColumnHeader := func(args, columns, sortedLinkers) {
239
239
 
240
240
 
241
241
 
242
- initializeCloneTable := func(pframes, columns, args, datasetSpec) {
242
+
243
+
244
+
245
+ initializeCloneTable := func(pframes, columns, args, datasetSpec, inputFilterColumn) {
243
246
 
244
247
  cloneTable := pframes.parquetFileBuilder()
245
248
  cloneTable.setAxisHeader(datasetSpec.axesSpec[1], "clonotypeKey")
246
-
249
+
247
250
 
248
251
  sortedLinkers := buildSortedLinkers(columns, datasetSpec)
249
-
252
+
250
253
 
251
254
  addedAxes := []
252
255
  filterMap := {}
253
256
  rankingMap := {}
254
257
  addedCols := false
255
-
258
+
259
+
260
+
261
+
262
+
263
+ if !is_undefined(inputFilterColumn) {
264
+ cloneTable.add(inputFilterColumn, {header: "primary_filter"})
265
+ addedCols = true
266
+ }
267
+
256
268
  if len(args.filters) > 0 {
257
269
  for i, filter in args.filters {
258
270
 
Binary file
package/package.json CHANGED
@@ -1,19 +1,19 @@
1
1
  {
2
2
  "name": "@platforma-open/milaboratories.top-antibodies.workflow",
3
- "version": "4.1.2",
3
+ "version": "4.2.0",
4
4
  "type": "module",
5
5
  "description": "Block Workflow",
6
6
  "dependencies": {
7
- "@platforma-sdk/workflow-tengo": "5.21.0",
7
+ "@platforma-sdk/workflow-tengo": "5.26.0",
8
8
  "@platforma-open/milaboratories.software-anarci": "^0.0.3",
9
9
  "@platforma-open/milaboratories.top-antibodies.sample-clonotypes": "2.1.4",
10
- "@platforma-open/milaboratories.top-antibodies.spectratype": "1.8.5",
11
10
  "@platforma-open/milaboratories.top-antibodies.umap": "1.2.5",
11
+ "@platforma-open/milaboratories.top-antibodies.assembling-fasta": "1.3.4",
12
12
  "@platforma-open/milaboratories.top-antibodies.anarci-kabat": "1.4.5",
13
- "@platforma-open/milaboratories.top-antibodies.assembling-fasta": "1.3.4"
13
+ "@platforma-open/milaboratories.top-antibodies.spectratype": "1.8.5"
14
14
  },
15
15
  "devDependencies": {
16
- "@platforma-sdk/tengo-builder": "2.5.26"
16
+ "@platforma-sdk/tengo-builder": "3.0.3"
17
17
  },
18
18
  "scripts": {
19
19
  "build": "shx rm -rf dist && pl-tengo check && pl-tengo build",
@@ -7,6 +7,7 @@ pframes := import("@platforma-sdk/workflow-tengo:pframes")
7
7
  slices := import("@platforma-sdk/workflow-tengo:slices")
8
8
  render := import("@platforma-sdk/workflow-tengo:render")
9
9
  pSpec := import("@platforma-sdk/workflow-tengo:pframes.spec")
10
+ smart := import("@platforma-sdk/workflow-tengo:smart")
10
11
  ll := import("@platforma-sdk/workflow-tengo:ll")
11
12
  kabatConv := import(":pf-kabat-conv")
12
13
 
@@ -25,8 +26,15 @@ wf.prepare(func(args){
25
26
  // We need a table with cluster ID (optional) | clonotype id | selected ranking columns
26
27
  bundleBuilder := wf.createPBundleBuilder()
27
28
  bundleBuilder.ignoreMissingDomains() // to make query work for both bulk and single cell data
28
- bundleBuilder.addAnchor("main", args.inputAnchor)
29
-
29
+ bundleBuilder.addAnchor("main", args.inputAnchor)
30
+
31
+ // Optional primary filter from PlDatasetSelector — inner-joined into the
32
+ // clone table below so the filter narrows every downstream stage
33
+ // (finalClonotypes, spectratype, Kabat, etc.).
34
+ if !is_undefined(args.inputFilter) {
35
+ bundleBuilder.addRef(args.inputFilter)
36
+ }
37
+
30
38
  validRanks := false
31
39
  if len(args.rankingOrder) > 0 {
32
40
  for col in args.rankingOrder {
@@ -149,10 +157,15 @@ wf.prepare(func(args){
149
157
  })
150
158
 
151
159
  wf.body(func(args) {
152
- // output containers
160
+ // output containers
153
161
  outputs := {}
154
162
  exports := {}
155
163
 
164
+ // Expose this block's own id so the model can drop self-produced filter
165
+ // entries from the dataset selector — without this the just-finished
166
+ // sampled subset shows up as a filter option on the next configuration.
167
+ outputs["selfBlockId"] = smart.createJsonResource(wf.getBlockId())
168
+
156
169
  if !is_undefined(args.inputAnchor) {
157
170
  // Input arguments
158
171
  columns := args.columns
@@ -164,8 +177,14 @@ wf.body(func(args) {
164
177
  isPeptide := datasetSpec.axesSpec[1].name == "pl7.app/variantKey"
165
178
 
166
179
  ////////// Clonotype Filtering //////////
167
- // Initialize and build clone table with all columns
168
- tableInit := utils.initializeCloneTable(pframes, columns, args, datasetSpec)
180
+ // Initialize and build clone table with all columns. When the user
181
+ // picked an optional primary filter in PlDatasetSelector, fetch the
182
+ // resolved column so initializeCloneTable can inner-join it.
183
+ inputFilterColumn := undefined
184
+ if !is_undefined(args.inputFilter) {
185
+ inputFilterColumn = columns.getColumn(args.inputFilter)
186
+ }
187
+ tableInit := utils.initializeCloneTable(pframes, columns, args, datasetSpec, inputFilterColumn)
169
188
  cloneTable := tableInit.cloneTable
170
189
  filterMap := tableInit.filterMap
171
190
  rankingMap := tableInit.rankingMap
@@ -232,27 +232,39 @@ resolveClusterColumnHeader := func(args, columns, sortedLinkers) {
232
232
  /**
233
233
  * Initializes and builds complete clone table with all columns.
234
234
  * Handles filters, ranking columns, linkers, cluster sizes, and fallback columns.
235
- *
235
+ *
236
236
  * @param pframes - PFrames import
237
237
  * @param columns - PBundle containing all columns
238
238
  * @param args - Arguments containing filters, rankingOrder, diversificationColumn
239
239
  * @param datasetSpec - Dataset specification with axes
240
+ * @param inputFilterColumn - Optional resolved column from the primary filter
241
+ * (PlDatasetSelector). Added with an inner join so missing keys are
242
+ * dropped from the clone table — narrows every downstream stage.
240
243
  * @return Map with keys: cloneTable, filterMap, rankingMap, sortedLinkers, clusterColumnHeader, addedCols
241
244
  */
242
- initializeCloneTable := func(pframes, columns, args, datasetSpec) {
245
+ initializeCloneTable := func(pframes, columns, args, datasetSpec, inputFilterColumn) {
243
246
  // Build clonotype table
244
247
  cloneTable := pframes.parquetFileBuilder()
245
248
  cloneTable.setAxisHeader(datasetSpec.axesSpec[1], "clonotypeKey")
246
-
249
+
247
250
  // Build linker list in SAME ORDER as model
248
251
  sortedLinkers := buildSortedLinkers(columns, datasetSpec)
249
-
252
+
250
253
  // Add Filters to table
251
254
  addedAxes := []
252
255
  filterMap := {}
253
256
  rankingMap := {}
254
257
  addedCols := false
255
-
258
+
259
+ // Apply the optional primary filter from PlDatasetSelector first. The
260
+ // builder's inner-join keeps the rows where every added column has a
261
+ // value, so once this column is present rows missing from the filter are
262
+ // dropped from the entire pipeline.
263
+ if !is_undefined(inputFilterColumn) {
264
+ cloneTable.add(inputFilterColumn, {header: "primary_filter"})
265
+ addedCols = true
266
+ }
267
+
256
268
  if len(args.filters) > 0 {
257
269
  for i, filter in args.filters {
258
270
  // we check for value presence and for actual pcolumn (cases where upstream block is deleted)