@platforma-open/milaboratories.mixcr-shm-trees.workflow 3.5.0 → 3.6.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,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.0 build /home/runner/work/mixcr-shm-trees/mixcr-shm-trees/workflow
3
+ > @platforma-open/milaboratories.mixcr-shm-trees.workflow@3.6.0 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.0
4
+
5
+ ### Minor Changes
6
+
7
+ - b8af059: SDK Upgrade
8
+ - b8af059: Custom library support
9
+
10
+ ## 3.5.1
11
+
12
+ ### Patch Changes
13
+
14
+ - 089219e: dependency upgrade
15
+
3
16
  ## 3.5.0
4
17
 
5
18
  ### Minor 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') }
@@ -1,18 +1,18 @@
1
1
  ll := import("@platforma-sdk/workflow-tengo:ll")
2
2
  text := import("text")
3
3
 
4
- // ==============================================
5
- //
6
- // Every function in this file will return:
7
- // pfconvParams - params to run xsv.importFileMap on exported files
8
- // cmdArgs - additional args for MiXCR to specify what fields to extract
9
- //
10
- // ==============================================
11
-
12
- // TODO: TMP
4
+
5
+
6
+
7
+
8
+
9
+
10
+
11
+
12
+
13
13
  allowNA := true
14
14
 
15
- // export of threes whithout nodes
15
+
16
16
  shmTreeTableOptions := func(dataDescription) {
17
17
  axes := []
18
18
  columns := []
@@ -300,7 +300,7 @@ shmTreeTableOptions := func(dataDescription) {
300
300
  }
301
301
  }
302
302
 
303
- // export data that is uniq for node
303
+
304
304
  shmTreeNodesTableOptions := func(dataDescription) {
305
305
  axes := []
306
306
  columns := []
@@ -361,7 +361,7 @@ shmTreeNodesTableOptions := func(dataDescription) {
361
361
  allowNA: false,
362
362
  spec: {
363
363
  name: "pl7.app/dendrogram/isObserved",
364
- // TODO change to Boolean when it will be supported
364
+
365
365
  valueType: "String",
366
366
  annotations: {
367
367
  "pl7.app/label": "Is observed in data",
@@ -811,8 +811,8 @@ shmTreeNodesTableOptions := func(dataDescription) {
811
811
  }
812
812
  }
813
813
 
814
- // export data that is unique for clones, but not unique for a node
815
- // (different clones could be in the same topology node, for example, different time points)
814
+
815
+
816
816
  shmTreeNodesWithClonesTableOptions := func(dataDescription, donorColumn) {
817
817
  donorColumnSpec := donorColumn.spec
818
818
 
@@ -870,8 +870,8 @@ shmTreeNodesWithClonesTableOptions := func(dataDescription, donorColumn) {
870
870
  cmdArgs = append(cmdArgs, "-fileName")
871
871
  axes = append(axes, {
872
872
  column: "fileName",
873
- // in case of single cell trees, not all subtrees will be filled for nodes with observed
874
- // allowNA: true,
873
+
874
+
875
875
  preProcess: [
876
876
  {
877
877
  type: "regexpReplace",
@@ -892,13 +892,13 @@ shmTreeNodesWithClonesTableOptions := func(dataDescription, donorColumn) {
892
892
  axes = append(axes, {
893
893
  column: "cloneId",
894
894
  id: "clone-id",
895
- // allowNA: true,
896
- // filtering off records without clones because we are not interested in them here
895
+
896
+
897
897
  filterOutRegex: "^$",
898
898
  spec: {
899
899
  name: "pl7.app/vdj/cloneId",
900
900
  type: "Long",
901
- // TODO domain with blockId
901
+
902
902
  annotations: {
903
903
  "pl7.app/label": "Clone id",
904
904
  "pl7.app/table/visibility": "default",
@@ -1135,7 +1135,7 @@ shmTreeNodesUniqueIsotypeTableOptions := func(dataDescription) {
1135
1135
  }
1136
1136
  }
1137
1137
 
1138
- // to use the file as a library, we should explicitly export functions
1138
+
1139
1139
  export ll.toStrict({
1140
1140
  shmTreeTableOptions: shmTreeTableOptions,
1141
1141
  shmTreeNodesTableOptions: shmTreeNodesTableOptions,
@@ -7,19 +7,19 @@ json := import("json")
7
7
  _P_COLUMN_DATA_RESOURCE_MAP := { Name: "PColumnData/ResourceMap", Version: "1" }
8
8
 
9
9
  groupDataByDonorId := func(donorColumn, datasets) {
10
- // we need to form a pColumn with two axes:
11
- // axes[0]: donorId
12
- // axes[1]: sampleId
13
- // axes[2]: mixcrclonotypingBlockId
14
- // value: fileRef resource
15
-
16
- // we have:
17
- // column of donorIds:
18
- // axes[0]: sampleId
19
- // value: donorId
20
- // several columns of clns:
21
- // axes[0]: sampleId
22
- // value: fileRef resource
10
+
11
+
12
+
13
+
14
+
15
+
16
+
17
+
18
+
19
+
20
+
21
+
22
+
23
23
 
24
24
  donorColumnSpec := donorColumn.spec
25
25
 
@@ -30,7 +30,7 @@ groupDataByDonorId := func(donorColumn, datasets) {
30
30
  name: "mixcr.com/clns",
31
31
  valueType: "File",
32
32
 
33
- // annotations and domain could differ between datasets
33
+
34
34
  axesSpec: [
35
35
  {
36
36
  name: donorColumnSpec.name,
@@ -49,20 +49,20 @@ groupDataByDonorId := func(donorColumn, datasets) {
49
49
  ]
50
50
  }, { removeUndefs: true })
51
51
 
52
- // creating sample to donor map
52
+
53
53
 
54
54
  sampleToDonor := {}
55
55
 
56
- // columns with meta could be fetched as data directly
56
+
57
57
  for k, v in donorColumn.data.getDataAsJson()["data"] {
58
58
  sampleId := json.decode(k)[0]
59
59
  sampleToDonor[sampleId] = v
60
60
  }
61
61
 
62
- // build pColumn by hand
62
+
63
63
  dataBuilder := smart.structBuilder(_P_COLUMN_DATA_RESOURCE_MAP, json.encode({ keyLength: 3 }))
64
64
 
65
- // collect all the clns files that we have into pColumn
65
+
66
66
  for clonotypingBlockId, dataset in datasets {
67
67
  for sKey, fileRef in dataset.data.inputs() {
68
68
  sampleId := json.decode(sKey)[0]
@@ -77,7 +77,7 @@ groupDataByDonorId := func(donorColumn, datasets) {
77
77
  }
78
78
  }
79
79
 
80
- // to use the file as a library, we should explicitly export functions
80
+
81
81
  export ll.toStrict({
82
82
  groupDataByDonorId: groupDataByDonorId
83
83
  })
@@ -4,7 +4,7 @@ assets := import("@platforma-sdk/workflow-tengo:assets")
4
4
  json := import("json")
5
5
  paggregateSw := assets.importSoftware("@platforma-open/milaboratories.software-ptransform:main")
6
6
 
7
- //// aggregating by-nodes output to make it uniquely addressable by it's native key
7
+
8
8
  ensureUniqueness := func(inputTsv, pfConvParams, ...aggParams) {
9
9
  keyColumns := []
10
10
  for axis in pfConvParams.axes {
Binary file
Binary file
Binary file
package/package.json CHANGED
@@ -1,21 +1,21 @@
1
1
  {
2
2
  "name": "@platforma-open/milaboratories.mixcr-shm-trees.workflow",
3
- "version": "3.5.0",
3
+ "version": "3.6.0",
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
+ "dependencies": {
10
+ "@platforma-sdk/workflow-tengo": "^4.2.0"
11
+ },
9
12
  "devDependencies": {
10
- "@platforma-sdk/tengo-builder": "^1.17.5",
11
- "@platforma-sdk/workflow-tengo": "^2.11.0",
12
- "@milaboratories/software-pframes-conv": "^2.1.9",
13
- "@platforma-open/milaboratories.software-small-binaries": "^1.15.7",
13
+ "@platforma-sdk/tengo-builder": "^2.1.3",
14
14
  "@platforma-open/milaboratories.software-mixcr": "4.7.0-139-develop",
15
15
  "@platforma-open/milaboratories.software-mitool": "2.3.1-5-main",
16
- "@platforma-open/milaboratories.software-ptransform": "^1.1.1",
17
- "@platforma-sdk/test": "^1.22.40",
18
- "vitest": "^2.1.8",
16
+ "@platforma-open/milaboratories.software-ptransform": "^1.3.1",
17
+ "@platforma-sdk/test": "^1.30.4",
18
+ "vitest": "~2.1.8",
19
19
  "typescript": "~5.6.3"
20
20
  },
21
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,7 @@ 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")
23
25
  self.awaitState("donorColumn", "ResourceReady")
24
26
  self.awaitState("params", "ResourceReady")
25
27
 
@@ -36,6 +38,8 @@ self.body(func(inputs) {
36
38
  cellsAssembled: false
37
39
  }
38
40
 
41
+ library := inputs.library
42
+
39
43
  // clonotypingBlockId -> "bulk" | "sc"
40
44
  datasetTypes := {}
41
45
 
@@ -78,6 +82,8 @@ self.body(func(inputs) {
78
82
  shmTreeNodesWithClonesTableOptions := exportSettings.shmTreeNodesWithClonesTableOptions(dataDescription, inputs.donorColumn)
79
83
  shmTreeNodesUniqueIsotypeTableOptions := exportSettings.shmTreeNodesUniqueIsotypeTableOptions(dataDescription)
80
84
 
85
+ libraryFormat := library.spec.annotations["pl7.app/vdj/libraryFormat"]
86
+
81
87
  // TODO that call is too low level. Should be replaced with something that works with pColumns, not data only
82
88
  mixcrResults := llPFrames.aggregate(
83
89
  // files to iterate through
@@ -131,9 +137,13 @@ self.body(func(inputs) {
131
137
  shmTreeNodesWithClonesTableOptions: shmTreeNodesWithClonesTableOptions,
132
138
  shmTreeNodesWithClonesTableArgs: shmTreeNodesWithClonesTableOptions.cmdArgs,
133
139
  shmTreeNodesUniqueIsotypeTableOptions: shmTreeNodesUniqueIsotypeTableOptions,
140
+ library: is_undefined(library) ? smart.createNullResource() : library.data,
134
141
  globalParams: maps.merge(
135
142
  inputs.params,
136
- { datasetTypes: datasetTypes }
143
+ {
144
+ datasetTypes: datasetTypes,
145
+ libraryFormat: libraryFormat
146
+ }
137
147
  )
138
148
  }
139
149
  )
@@ -143,7 +153,7 @@ self.body(func(inputs) {
143
153
  additionalAxesSpec: dataGroupedByDonorId.spec["axesSpec"][:1]
144
154
  }
145
155
 
146
- ll.print("__THE_LOG__ " + string(json.encode(additionalArgsForImportTsv)))
156
+ // ll.print("__THE_LOG__ " + string(json.encode(additionalArgsForImportTsv)))
147
157
 
148
158
  trees := xsv.importFileMap(
149
159
  mixcrResults.output("trees"),
@@ -33,19 +33,32 @@ self.body(func(inputs) {
33
33
  globalParams := inputs.globalParams
34
34
  datasetTypes := globalParams.datasetTypes
35
35
  downsampling := globalParams.downsampling
36
+ library := inputs.library
37
+ libraryFormat := globalParams.libraryFormat
36
38
 
37
39
  // ll.print("__THE_LOG__ " + json.encode(datasetTypes))
38
40
  // ll.print("__THE_LOG__ " + json.encode(downsampling))
41
+ // ll.print("__THE_LOG__ " + json.encode(libraryFormat))
39
42
 
40
43
  ll.assert(!is_undefined(datasetTypes), "datasetTypes undefined")
41
44
 
42
- seed := times.time_string(times.now())
45
+ addLibraryFile := func(cmdBuilder) {
46
+ if !is_undefined(library) {
47
+ if libraryFormat == "repseqio.json.gz" {
48
+ cmdBuilder.addFile("library.json.gz", library)
49
+ } else {
50
+ cmdBuilder.addFile("library.json", library)
51
+ }
52
+ }
53
+ }
54
+
55
+ // seed := times.time_string(times.now())
43
56
 
44
57
  allelesCmdBuilder := exec.builder().
45
58
  printErrStreamToStdout().
46
59
  secret("MI_LICENSE", "MI_LICENSE").
47
60
  env("MI_PROGRESS_PREFIX", progressPrefix).
48
- env("SEED", seed).
61
+ // env("SEED", seed).
49
62
  software(mixcrSw).
50
63
  arg("findAlleles").
51
64
  arg("--report").arg("report.txt").
@@ -55,6 +68,8 @@ self.body(func(inputs) {
55
68
  // template specifies where result files will be written
56
69
  arg("--output-template").arg("alleles/{file_name}.clns")
57
70
 
71
+ addLibraryFile(allelesCmdBuilder)
72
+
58
73
  if !is_undefined(globalParams.seed) {
59
74
  allelesCmdBuilder.env("SEED", globalParams.seed)
60
75
  }
@@ -108,7 +123,7 @@ self.body(func(inputs) {
108
123
 
109
124
  for input in toProcess {
110
125
  if datasetTypes[input.clonotypingBlockId] == "bulk" {
111
- downsamplingCmd := exec.builder().
126
+ downsamplingCmdBuilder := exec.builder().
112
127
  printErrStreamToStdout().
113
128
  secret("MI_LICENSE", "MI_LICENSE").
114
129
  env("MI_PROGRESS_PREFIX", progressPrefix).
@@ -118,8 +133,9 @@ self.body(func(inputs) {
118
133
  arg(downsamplingParam).
119
134
  arg("clones.clns").
120
135
  addFile("clones.clns", input.alleles).
121
- saveFile("clones.downsampled.clns").
122
- run()
136
+ saveFile("clones.downsampled.clns")
137
+ addLibraryFile(downsamplingCmdBuilder)
138
+ downsamplingCmd := downsamplingCmdBuilder.run()
123
139
  input.alleles = downsamplingCmd.getFile("clones.downsampled.clns")
124
140
  }
125
141
  }
@@ -129,7 +145,6 @@ self.body(func(inputs) {
129
145
  printErrStreamToStdout().
130
146
  secret("MI_LICENSE", "MI_LICENSE").
131
147
  env("MI_PROGRESS_PREFIX", progressPrefix).
132
- env("SEED", seed).
133
148
  software(mixcrSw).
134
149
  arg("findShmTrees").
135
150
  arg("--report").arg("report.txt").
@@ -141,6 +156,8 @@ self.body(func(inputs) {
141
156
  shmTreesCmdBuilder.env("SEED", globalParams.seed)
142
157
  }
143
158
 
159
+ addLibraryFile(shmTreesCmdBuilder)
160
+
144
161
  for input in toProcess {
145
162
  shmTreesCmdBuilder.
146
163
  addFile(input.fileName, input.alleles).
@@ -151,15 +168,18 @@ self.body(func(inputs) {
151
168
 
152
169
  shmTrees := shmTreesCmdBuilder.run()
153
170
  outputShmt := shmTrees.getFile("output.shmt")
154
-
171
+
155
172
  // export trees without nodes
156
173
  shmTreeExportsCmdBuilder := exec.builder().
157
174
  printErrStreamToStdout().
175
+ dontSaveStdoutOrStderr().
158
176
  inLightQueue().
159
177
  secret("MI_LICENSE", "MI_LICENSE").
160
178
  software(mixcrSw).
161
179
  arg("exportShmTrees")
162
180
 
181
+ addLibraryFile(shmTreeExportsCmdBuilder)
182
+
163
183
  for arg in inputs.shmTreeTableArgs {
164
184
  shmTreeExportsCmdBuilder = shmTreeExportsCmdBuilder.arg(arg)
165
185
  }
@@ -178,11 +198,14 @@ self.body(func(inputs) {
178
198
  // export tree nodes with data uniq for the node
179
199
  shmTreeNodesExportsCmdBuilder := exec.builder().
180
200
  printErrStreamToStdout().
201
+ dontSaveStdoutOrStderr().
181
202
  inLightQueue().
182
203
  secret("MI_LICENSE", "MI_LICENSE").
183
204
  software(mixcrSw).
184
205
  arg("exportShmTreesWithNodes")
185
206
 
207
+ addLibraryFile(shmTreeNodesExportsCmdBuilder)
208
+
186
209
  for arg in inputs.shmTreeNodesTableOptions.cmdArgs {
187
210
  shmTreeNodesExportsCmdBuilder = shmTreeNodesExportsCmdBuilder.arg(arg)
188
211
  }
@@ -201,6 +224,7 @@ self.body(func(inputs) {
201
224
  // export nodes with clones. For each node could be several clones
202
225
  shmTreeNodesWithClonesExportsCmdBuilder := exec.builder().
203
226
  printErrStreamToStdout().
227
+ dontSaveStdoutOrStderr().
204
228
  inLightQueue().
205
229
  secret("MI_LICENSE", "MI_LICENSE").
206
230
  env("MI_PROGRESS_PREFIX", progressPrefix).
@@ -209,6 +233,8 @@ self.body(func(inputs) {
209
233
  // don't export nodes that don't have clones
210
234
  arg("--only-observed")
211
235
 
236
+ addLibraryFile(shmTreeNodesWithClonesExportsCmdBuilder)
237
+
212
238
  for arg in inputs.shmTreeNodesWithClonesTableArgs {
213
239
  shmTreeNodesWithClonesExportsCmdBuilder = shmTreeNodesWithClonesExportsCmdBuilder.arg(arg)
214
240
  }
@@ -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
+