@platforma-open/milaboratories.mixcr-shm-trees.workflow 3.5.1 → 3.6.1

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,5 +1,6 @@
1
+  WARN  Issue while reading "/home/runner/work/mixcr-shm-trees/mixcr-shm-trees/.npmrc". Failed to replace env in config: ${NPMJS_TOKEN}
1
2
 
2
- > @platforma-open/milaboratories.mixcr-shm-trees.workflow@3.5.1 build /home/runner/work/mixcr-shm-trees/mixcr-shm-trees/workflow
3
+ > @platforma-open/milaboratories.mixcr-shm-trees.workflow@3.6.1 build /home/runner/work/mixcr-shm-trees/mixcr-shm-trees/workflow
3
4
  > rm -rf dist && pl-tengo check && pl-tengo build
4
5
 
5
6
  Processing "src/export-settings.lib.tengo"...
@@ -7,6 +8,7 @@ Processing "src/main.tpl.tengo"...
7
8
  Processing "src/prepare-donor-column.lib.tengo"...
8
9
  Processing "src/process.tpl.tengo"...
9
10
  Processing "src/reconstruct-shm-trees.tpl.tengo"...
11
+ Processing "src/request-library.tpl.tengo"...
10
12
  Processing "src/soi-export.lib.tengo"...
11
13
  Processing "src/soi.tpl.tengo"...
12
14
  Processing "src/tablesAggregation.lib.tengo"...
@@ -17,8 +19,9 @@ No syntax errors found.
17
19
  info: - writing /home/runner/work/mixcr-shm-trees/mixcr-shm-trees/workflow/dist/tengo/lib/soi-export.lib.tengo
18
20
  info: - writing /home/runner/work/mixcr-shm-trees/mixcr-shm-trees/workflow/dist/tengo/lib/tablesAggregation.lib.tengo
19
21
  info: - writing /home/runner/work/mixcr-shm-trees/mixcr-shm-trees/workflow/dist/tengo/tpl/reconstruct-shm-trees.plj.gz
22
+ info: - writing /home/runner/work/mixcr-shm-trees/mixcr-shm-trees/workflow/dist/tengo/tpl/request-library.plj.gz
20
23
  info: - writing /home/runner/work/mixcr-shm-trees/mixcr-shm-trees/workflow/dist/tengo/tpl/soi.plj.gz
21
24
  info: - writing /home/runner/work/mixcr-shm-trees/mixcr-shm-trees/workflow/dist/tengo/tpl/process.plj.gz
22
25
  info: - writing /home/runner/work/mixcr-shm-trees/mixcr-shm-trees/workflow/dist/tengo/tpl/main.plj.gz
23
- info:
26
+ info: Template Pack build done.
24
27
  info: Template Pack build done.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,18 @@
1
1
  # @platforma-open/milaboratories.mixcr-shm-trees.workflow
2
2
 
3
+ ## 3.6.1
4
+
5
+ ### Patch Changes
6
+
7
+ - 9e53ea9: Fix for await criteria
8
+
9
+ ## 3.6.0
10
+
11
+ ### Minor Changes
12
+
13
+ - b8af059: SDK Upgrade
14
+ - b8af059: Custom library support
15
+
3
16
  ## 3.5.1
4
17
 
5
18
  ### Patch Changes
package/dist/index.cjs CHANGED
@@ -1,5 +1,6 @@
1
1
  module.exports = { Templates: {
2
2
  'reconstruct-shm-trees': { type: 'from-file', path: require.resolve('./tengo/tpl/reconstruct-shm-trees.plj.gz') },
3
+ 'request-library': { type: 'from-file', path: require.resolve('./tengo/tpl/request-library.plj.gz') },
3
4
  'soi': { type: 'from-file', path: require.resolve('./tengo/tpl/soi.plj.gz') },
4
5
  'process': { type: 'from-file', path: require.resolve('./tengo/tpl/process.plj.gz') },
5
6
  'main': { type: 'from-file', path: require.resolve('./tengo/tpl/main.plj.gz') }
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
1
  declare type TemplateFromFile = { readonly type: "from-file"; readonly path: string; };
2
- declare type TplName = "reconstruct-shm-trees" | "soi" | "process" | "main";
2
+ declare type TplName = "reconstruct-shm-trees" | "request-library" | "soi" | "process" | "main";
3
3
  declare const Templates: Record<TplName, TemplateFromFile>;
4
4
  export { Templates };
package/dist/index.js CHANGED
@@ -1,6 +1,7 @@
1
1
  import { resolve } from 'node:path';
2
2
  export const Templates = {
3
3
  'reconstruct-shm-trees': { type: 'from-file', path: resolve(import.meta.dirname, './tengo/tpl/reconstruct-shm-trees.plj.gz') },
4
+ 'request-library': { type: 'from-file', path: resolve(import.meta.dirname, './tengo/tpl/request-library.plj.gz') },
4
5
  'soi': { type: 'from-file', path: resolve(import.meta.dirname, './tengo/tpl/soi.plj.gz') },
5
6
  'process': { type: 'from-file', path: resolve(import.meta.dirname, './tengo/tpl/process.plj.gz') },
6
7
  'main': { type: 'from-file', path: resolve(import.meta.dirname, './tengo/tpl/main.plj.gz') }
Binary file
Binary file
Binary file
package/package.json CHANGED
@@ -1,23 +1,21 @@
1
1
  {
2
2
  "name": "@platforma-open/milaboratories.mixcr-shm-trees.workflow",
3
- "version": "3.5.1",
3
+ "version": "3.6.1",
4
4
  "type": "module",
5
5
  "description": "Tengo-based template",
6
6
  "//": {
7
7
  "build": "node ./scripts/build-static.mjs src/pfconv_params.json src/pfconv_params.lib.tengo && rm -rf dist && pl-tengo check && pl-tengo build && ./create_tags.sh"
8
8
  },
9
9
  "dependencies": {
10
- "@platforma-sdk/workflow-tengo": "^3.1.0"
10
+ "@platforma-sdk/workflow-tengo": "^4.2.0"
11
11
  },
12
12
  "devDependencies": {
13
- "@platforma-sdk/tengo-builder": "^2.0.2",
14
- "@milaboratories/software-pframes-conv": "^2.1.20",
15
- "@platforma-open/milaboratories.software-small-binaries": "^1.15.19",
13
+ "@platforma-sdk/tengo-builder": "^2.1.3",
16
14
  "@platforma-open/milaboratories.software-mixcr": "4.7.0-139-develop",
17
15
  "@platforma-open/milaboratories.software-mitool": "2.3.1-5-main",
18
16
  "@platforma-open/milaboratories.software-ptransform": "^1.3.1",
19
- "@platforma-sdk/test": "^1.25.0",
20
- "vitest": "^2.1.8",
17
+ "@platforma-sdk/test": "^1.30.4",
18
+ "vitest": "~2.1.8",
21
19
  "typescript": "~5.6.3"
22
20
  },
23
21
  "scripts": {
@@ -6,6 +6,7 @@ ll := import("@platforma-sdk/workflow-tengo:ll")
6
6
  pframes := import("@platforma-sdk/workflow-tengo:pframes")
7
7
 
8
8
  processTpl := assets.importTemplate(":process")
9
+ requestLibraryTpl := assets.importTemplate(":request-library")
9
10
 
10
11
  wf.body(func(args) {
11
12
  if is_undefined(args.donorColumn) {
@@ -19,13 +20,15 @@ wf.body(func(args) {
19
20
  // we could not use array as request for waiting (see below), so we store datasets in a dictionary
20
21
  datasets := {}
21
22
  for datasetRef in args.datasetColumns {
22
- if is_undefined(datasetRef) {
23
- ll.panic("Dataset is undefined")
24
- }
25
- // it's blockId of MiXCR, we suppose that it procuce only one clns column
23
+ // we assume that mixcr block produces exactly one clns column
26
24
  datasets[datasetRef.blockId] = wf.resolve(datasetRef)
27
25
  }
28
26
 
27
+ library := render.createEphemeral(requestLibraryTpl, {
28
+ datasets: datasets,
29
+ ctx: wf.getParentBCtx()
30
+ }).output("library")
31
+
29
32
  donorColumn := wf.resolve(args.donorColumn)
30
33
 
31
34
  // The problem is that refs for data is not resolved.
@@ -34,6 +37,7 @@ wf.body(func(args) {
34
37
  results := render.createEphemeral(processTpl, {
35
38
  datasets: datasets,
36
39
  donorColumn: donorColumn,
40
+ library: library,
37
41
  params: {
38
42
  downsampling: args.downsampling,
39
43
  sequencesOfInterest: args.sequencesOfInterest
@@ -6,6 +6,7 @@ maps := import("@platforma-sdk/workflow-tengo:maps")
6
6
  assets := import("@platforma-sdk/workflow-tengo:assets")
7
7
  render := import("@platforma-sdk/workflow-tengo:render")
8
8
  xsv := import("@platforma-sdk/workflow-tengo:pframes.xsv")
9
+ smart := import("@platforma-sdk/workflow-tengo:smart")
9
10
  text := import("text")
10
11
  json := import("json")
11
12
  exportSettings := import(":export-settings")
@@ -20,6 +21,8 @@ self.awaitState("datasets", { wildcard: "*" }, "AllInputsSet")
20
21
  self.awaitState("datasets", { wildcard: "*" }, "data", "InputsLocked")
21
22
  // but we need spec already
22
23
  self.awaitState("datasets", { wildcard: "*" }, "spec", "ResourceReady")
24
+ self.awaitState("library", "spec", "ResourceReady")
25
+ self.awaitState("library", "data", "AllInputsSet") // change to InputsLocked after fix
23
26
  self.awaitState("donorColumn", "ResourceReady")
24
27
  self.awaitState("params", "ResourceReady")
25
28
 
@@ -36,6 +39,8 @@ self.body(func(inputs) {
36
39
  cellsAssembled: false
37
40
  }
38
41
 
42
+ library := inputs.library
43
+
39
44
  // clonotypingBlockId -> "bulk" | "sc"
40
45
  datasetTypes := {}
41
46
 
@@ -78,6 +83,8 @@ self.body(func(inputs) {
78
83
  shmTreeNodesWithClonesTableOptions := exportSettings.shmTreeNodesWithClonesTableOptions(dataDescription, inputs.donorColumn)
79
84
  shmTreeNodesUniqueIsotypeTableOptions := exportSettings.shmTreeNodesUniqueIsotypeTableOptions(dataDescription)
80
85
 
86
+ libraryFormat := library.spec.annotations["pl7.app/vdj/libraryFormat"]
87
+
81
88
  // TODO that call is too low level. Should be replaced with something that works with pColumns, not data only
82
89
  mixcrResults := llPFrames.aggregate(
83
90
  // files to iterate through
@@ -131,9 +138,13 @@ self.body(func(inputs) {
131
138
  shmTreeNodesWithClonesTableOptions: shmTreeNodesWithClonesTableOptions,
132
139
  shmTreeNodesWithClonesTableArgs: shmTreeNodesWithClonesTableOptions.cmdArgs,
133
140
  shmTreeNodesUniqueIsotypeTableOptions: shmTreeNodesUniqueIsotypeTableOptions,
141
+ library: is_undefined(library) ? smart.createNullResource() : library.data,
134
142
  globalParams: maps.merge(
135
143
  inputs.params,
136
- { datasetTypes: datasetTypes }
144
+ {
145
+ datasetTypes: datasetTypes,
146
+ libraryFormat: libraryFormat
147
+ }
137
148
  )
138
149
  }
139
150
  )
@@ -143,7 +154,7 @@ self.body(func(inputs) {
143
154
  additionalAxesSpec: dataGroupedByDonorId.spec["axesSpec"][:1]
144
155
  }
145
156
 
146
- ll.print("__THE_LOG__ " + string(json.encode(additionalArgsForImportTsv)))
157
+ // ll.print("__THE_LOG__ " + string(json.encode(additionalArgsForImportTsv)))
147
158
 
148
159
  trees := xsv.importFileMap(
149
160
  mixcrResults.output("trees"),
@@ -33,19 +33,28 @@ self.body(func(inputs) {
33
33
  globalParams := inputs.globalParams
34
34
  datasetTypes := globalParams.datasetTypes
35
35
  downsampling := globalParams.downsampling
36
-
37
- // ll.print("__THE_LOG__ " + json.encode(datasetTypes))
38
- // ll.print("__THE_LOG__ " + json.encode(downsampling))
36
+ library := inputs.library
37
+ libraryFormat := globalParams.libraryFormat
39
38
 
40
39
  ll.assert(!is_undefined(datasetTypes), "datasetTypes undefined")
41
40
 
42
- seed := times.time_string(times.now())
41
+ addLibraryFile := func(cmdBuilder) {
42
+ if !is_undefined(library) {
43
+ if libraryFormat == "repseqio.json.gz" {
44
+ cmdBuilder.addFile("library.json.gz", library)
45
+ } else {
46
+ cmdBuilder.addFile("library.json", library)
47
+ }
48
+ }
49
+ }
50
+
51
+ // seed := times.time_string(times.now())
43
52
 
44
53
  allelesCmdBuilder := exec.builder().
45
54
  printErrStreamToStdout().
46
55
  secret("MI_LICENSE", "MI_LICENSE").
47
56
  env("MI_PROGRESS_PREFIX", progressPrefix).
48
- env("SEED", seed).
57
+ // env("SEED", seed).
49
58
  software(mixcrSw).
50
59
  arg("findAlleles").
51
60
  arg("--report").arg("report.txt").
@@ -55,6 +64,8 @@ self.body(func(inputs) {
55
64
  // template specifies where result files will be written
56
65
  arg("--output-template").arg("alleles/{file_name}.clns")
57
66
 
67
+ addLibraryFile(allelesCmdBuilder)
68
+
58
69
  if !is_undefined(globalParams.seed) {
59
70
  allelesCmdBuilder.env("SEED", globalParams.seed)
60
71
  }
@@ -104,11 +115,9 @@ self.body(func(inputs) {
104
115
  ll.panic("Unknown downsampling type: " + downsampling.type)
105
116
  }
106
117
 
107
- // ll.print("__THE_LOG__ " + downsamplingParam)
108
-
109
118
  for input in toProcess {
110
119
  if datasetTypes[input.clonotypingBlockId] == "bulk" {
111
- downsamplingCmd := exec.builder().
120
+ downsamplingCmdBuilder := exec.builder().
112
121
  printErrStreamToStdout().
113
122
  secret("MI_LICENSE", "MI_LICENSE").
114
123
  env("MI_PROGRESS_PREFIX", progressPrefix).
@@ -118,8 +127,9 @@ self.body(func(inputs) {
118
127
  arg(downsamplingParam).
119
128
  arg("clones.clns").
120
129
  addFile("clones.clns", input.alleles).
121
- saveFile("clones.downsampled.clns").
122
- run()
130
+ saveFile("clones.downsampled.clns")
131
+ addLibraryFile(downsamplingCmdBuilder)
132
+ downsamplingCmd := downsamplingCmdBuilder.run()
123
133
  input.alleles = downsamplingCmd.getFile("clones.downsampled.clns")
124
134
  }
125
135
  }
@@ -129,7 +139,6 @@ self.body(func(inputs) {
129
139
  printErrStreamToStdout().
130
140
  secret("MI_LICENSE", "MI_LICENSE").
131
141
  env("MI_PROGRESS_PREFIX", progressPrefix).
132
- env("SEED", seed).
133
142
  software(mixcrSw).
134
143
  arg("findShmTrees").
135
144
  arg("--report").arg("report.txt").
@@ -141,6 +150,8 @@ self.body(func(inputs) {
141
150
  shmTreesCmdBuilder.env("SEED", globalParams.seed)
142
151
  }
143
152
 
153
+ addLibraryFile(shmTreesCmdBuilder)
154
+
144
155
  for input in toProcess {
145
156
  shmTreesCmdBuilder.
146
157
  addFile(input.fileName, input.alleles).
@@ -151,15 +162,18 @@ self.body(func(inputs) {
151
162
 
152
163
  shmTrees := shmTreesCmdBuilder.run()
153
164
  outputShmt := shmTrees.getFile("output.shmt")
154
-
165
+
155
166
  // export trees without nodes
156
167
  shmTreeExportsCmdBuilder := exec.builder().
157
168
  printErrStreamToStdout().
169
+ dontSaveStdoutOrStderr().
158
170
  inLightQueue().
159
171
  secret("MI_LICENSE", "MI_LICENSE").
160
172
  software(mixcrSw).
161
173
  arg("exportShmTrees")
162
174
 
175
+ addLibraryFile(shmTreeExportsCmdBuilder)
176
+
163
177
  for arg in inputs.shmTreeTableArgs {
164
178
  shmTreeExportsCmdBuilder = shmTreeExportsCmdBuilder.arg(arg)
165
179
  }
@@ -178,11 +192,14 @@ self.body(func(inputs) {
178
192
  // export tree nodes with data uniq for the node
179
193
  shmTreeNodesExportsCmdBuilder := exec.builder().
180
194
  printErrStreamToStdout().
195
+ dontSaveStdoutOrStderr().
181
196
  inLightQueue().
182
197
  secret("MI_LICENSE", "MI_LICENSE").
183
198
  software(mixcrSw).
184
199
  arg("exportShmTreesWithNodes")
185
200
 
201
+ addLibraryFile(shmTreeNodesExportsCmdBuilder)
202
+
186
203
  for arg in inputs.shmTreeNodesTableOptions.cmdArgs {
187
204
  shmTreeNodesExportsCmdBuilder = shmTreeNodesExportsCmdBuilder.arg(arg)
188
205
  }
@@ -201,6 +218,7 @@ self.body(func(inputs) {
201
218
  // export nodes with clones. For each node could be several clones
202
219
  shmTreeNodesWithClonesExportsCmdBuilder := exec.builder().
203
220
  printErrStreamToStdout().
221
+ dontSaveStdoutOrStderr().
204
222
  inLightQueue().
205
223
  secret("MI_LICENSE", "MI_LICENSE").
206
224
  env("MI_PROGRESS_PREFIX", progressPrefix).
@@ -209,6 +227,8 @@ self.body(func(inputs) {
209
227
  // don't export nodes that don't have clones
210
228
  arg("--only-observed")
211
229
 
230
+ addLibraryFile(shmTreeNodesWithClonesExportsCmdBuilder)
231
+
212
232
  for arg in inputs.shmTreeNodesWithClonesTableArgs {
213
233
  shmTreeNodesWithClonesExportsCmdBuilder = shmTreeNodesWithClonesExportsCmdBuilder.arg(arg)
214
234
  }
@@ -0,0 +1,42 @@
1
+ smart := import("@platforma-sdk/workflow-tengo:smart")
2
+ bquery := import("@platforma-sdk/workflow-tengo:workflow.bquery")
3
+ ll := import("@platforma-sdk/workflow-tengo:ll")
4
+ self := import("@platforma-sdk/workflow-tengo:tpl")
5
+
6
+ self.awaitState("datasets", { wildcard: "*" }, "spec", "ResourceReady")
7
+ self.awaitState("datasets", { wildcard: "*" }, "ref", "ResourceReady")
8
+
9
+ self.body(func(args) {
10
+ datasets := args.datasets
11
+ ctx := args.ctx
12
+
13
+ // undefined - not initialized
14
+ // "" - no custom library, built-in library will be used
15
+ // "...." - custom library id, to be requested from the context
16
+ libraryId := undefined
17
+
18
+ for _, dataset in datasets {
19
+ dsLibraryId := dataset.spec.annotations["pl7.app/vdj/libraryId"]
20
+ if is_undefined(libraryId) {
21
+ libraryId = !is_undefined(dsLibraryId) ? dsLibraryId : ""
22
+ } else {
23
+ if libraryId != dsLibraryId {
24
+ ll.panic("All datasets should have the same libraryId. Got " + libraryId + " and " + dsLibraryId)
25
+ }
26
+ }
27
+ }
28
+
29
+ if libraryId == "" || is_undefined(libraryId) {
30
+ return { library: smart.createNullResource() }
31
+ } else {
32
+ querySpec := {
33
+ type: "And",
34
+ operands: [
35
+ { type: "Name", name: "pl7.app/vdj/library" },
36
+ { type: "Domain", domain: { "pl7.app/vdj/libraryId": libraryId } }
37
+ ]
38
+ }
39
+ return { library: bquery.create(querySpec, ctx, { single: true, errIfMissing: true }) }
40
+ }
41
+ })
42
+