@platforma-open/milaboratories.samples-and-data.workflow 1.13.2 → 2.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.
package/dist/index.cjs CHANGED
@@ -1,3 +1,5 @@
1
1
  module.exports = { Templates: {
2
+ 'parse-bulk-count-matrix': { type: 'from-file', path: require.resolve('./tengo/tpl/parse-bulk-count-matrix.plj.gz') },
3
+ 'prerun': { type: 'from-file', path: require.resolve('./tengo/tpl/prerun.plj.gz') },
2
4
  'main': { type: 'from-file', path: require.resolve('./tengo/tpl/main.plj.gz') }
3
5
  }};
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 = "main";
2
+ declare type TplName = "parse-bulk-count-matrix" | "prerun" | "main";
3
3
  declare const Templates: Record<TplName, TemplateFromFile>;
4
4
  export { Templates };
package/dist/index.js CHANGED
@@ -1,4 +1,6 @@
1
1
  import { resolve } from 'node:path';
2
2
  export const Templates = {
3
+ 'parse-bulk-count-matrix': { type: 'from-file', path: resolve(import.meta.dirname, './tengo/tpl/parse-bulk-count-matrix.plj.gz') },
4
+ 'prerun': { type: 'from-file', path: resolve(import.meta.dirname, './tengo/tpl/prerun.plj.gz') },
3
5
  'main': { type: 'from-file', path: resolve(import.meta.dirname, './tengo/tpl/main.plj.gz') }
4
6
  };
@@ -0,0 +1,67 @@
1
+
2
+ ll := import("@platforma-sdk/workflow-tengo:ll")
3
+ pt := import("@platforma-sdk/workflow-tengo:pt")
4
+ render := import("@platforma-sdk/workflow-tengo:render")
5
+ assets := import("@platforma-sdk/workflow-tengo:assets")
6
+ pColumn := import("@platforma-sdk/workflow-tengo:pframes.pcolumn")
7
+ txt := import("@platforma-sdk/workflow-tengo:txt")
8
+ parseHeaderTpl := assets.importTemplate("@platforma-open/milaboratories.samples-and-data.workflow:parse-bulk-count-matrix")
9
+
10
+ util := import("@platforma-open/milaboratories.samples-and-data.workflow:util")
11
+
12
+ export {
13
+ isGrouped: true,
14
+
15
+ getSamples: func(dataset, importFile) {
16
+
17
+ result := {}
18
+ for groupId, importHandle in dataset.content.data {
19
+ if !importHandle {
20
+ ll.panic("File handle not set for group %v", groupId)
21
+ }
22
+
23
+ headerContent := txt.head(importFile(importHandle), {lines: 1})
24
+
25
+ separator := "\t"
26
+ if dataset.content.xsvType == "tsv" {
27
+ separator = "\t"
28
+ } else if dataset.content.xsvType == "csv" {
29
+ separator = ","
30
+ } else {
31
+ ll.panic("Unsupported file extension: " + dataset.content.xsvType)
32
+ }
33
+
34
+ samples := render.create(parseHeaderTpl, {
35
+ header: headerContent,
36
+ delimiter: separator
37
+ }).output("samples")
38
+
39
+ result[groupId] = samples
40
+ }
41
+ return result
42
+ },
43
+
44
+ createDataset: func(blockId, sampleIdAxis, groupIdAxis, dataset, importFile) {
45
+
46
+ extension := dataset.content.xsvType + (dataset.content.gzipped ? ".gz" : "")
47
+
48
+ spec := util.datasetColumnSpecBase(blockId, dataset, extension)
49
+ spec.axesSpec = [groupIdAxis]
50
+
51
+ data := pColumn.resourceMapBuilder(1)
52
+ for groupId, importHandle in dataset.content.data {
53
+ if !importHandle {
54
+ ll.panic("File handle not set for sample %v", groupId)
55
+ }
56
+ data.add([groupId], importFile(importHandle))
57
+ }
58
+
59
+ result := {}
60
+ result["dataset." + dataset.id] = {
61
+ spec: spec,
62
+ data: data.build()
63
+ }
64
+
65
+ return result
66
+ }
67
+ }
@@ -0,0 +1,47 @@
1
+
2
+ ll := import("@platforma-sdk/workflow-tengo:ll")
3
+ pColumn := import("@platforma-sdk/workflow-tengo:pframes.pcolumn")
4
+ util := import("@platforma-open/milaboratories.samples-and-data.workflow:util")
5
+
6
+ cellRangerMtxRoles := ["matrix.mtx", "features.tsv", "barcodes.tsv"]
7
+
8
+ export {
9
+ isGrouped: false,
10
+
11
+ createDataset: func(blockId, sampleIdAxis, dataset, importFile) {
12
+ compression := dataset.content.gzipped ? "gz" : "none"
13
+
14
+ spec := util.datasetColumnSpecBase(blockId, dataset, undefined)
15
+ spec.domain["pl7.app/compression"] = compression
16
+
17
+ cellRangerFileRoleAxisSpec := {
18
+ type: "String",
19
+ name: "pl7.app/sc/cellRangerFileRole",
20
+ annotations: {
21
+ "pl7.app/label": "Role"
22
+ }
23
+ }
24
+
25
+ spec.axesSpec = [sampleIdAxis, cellRangerFileRoleAxisSpec]
26
+
27
+ data := pColumn.resourceMapBuilder(2)
28
+ for sampleId, fileGroup in dataset.content.data {
29
+ for role in cellRangerMtxRoles {
30
+ importHandle := fileGroup[role]
31
+ if !importHandle {
32
+ ll.panic("File handle not set for %v in sample %v", role, sampleId)
33
+ }
34
+ data.add([sampleId, role], importFile(importHandle))
35
+ }
36
+ }
37
+
38
+ result := {}
39
+ result["dataset." + dataset.id] = {
40
+ spec: spec,
41
+ data: data.build()
42
+ }
43
+
44
+ return result
45
+ }
46
+ }
47
+
@@ -0,0 +1,32 @@
1
+
2
+ ll := import("@platforma-sdk/workflow-tengo:ll")
3
+ pColumn := import("@platforma-sdk/workflow-tengo:pframes.pcolumn")
4
+
5
+ util := import("@platforma-open/milaboratories.samples-and-data.workflow:util")
6
+
7
+ export {
8
+ isGrouped: false,
9
+
10
+ createDataset: func(blockId, sampleIdAxis, dataset, importFile) {
11
+ extension := dataset.content.gzipped ? "fasta.gz" : "fasta"
12
+
13
+ spec := util.datasetColumnSpecBase(blockId, dataset, extension)
14
+ spec.axesSpec = [sampleIdAxis]
15
+
16
+ data := pColumn.resourceMapBuilder(1)
17
+ for sampleId, importHandle in dataset.content.data {
18
+ if !importHandle {
19
+ ll.panic("File handle not set for sample %v", sampleId)
20
+ }
21
+ data.add([sampleId], importFile(importHandle))
22
+ }
23
+
24
+ result := {}
25
+ result["dataset." + dataset.id] = {
26
+ spec: spec,
27
+ data: data.build()
28
+ }
29
+
30
+ return result
31
+ }
32
+ }
@@ -0,0 +1,51 @@
1
+
2
+ ll := import("@platforma-sdk/workflow-tengo:ll")
3
+ pColumn := import("@platforma-sdk/workflow-tengo:pframes.pcolumn")
4
+ json := import("json")
5
+ util := import("@platforma-open/milaboratories.samples-and-data.workflow:util")
6
+
7
+ export {
8
+ isGrouped: false,
9
+
10
+ createDataset: func(blockId, sampleIdAxis, dataset, importFile) {
11
+ extension := dataset.content.gzipped ? "fastq.gz" : "fastq"
12
+
13
+ spec := util.datasetColumnSpecBase(blockId, dataset, extension)
14
+
15
+ readIndexAxisSpec := {
16
+ type: "String",
17
+ name: "pl7.app/sequencing/readIndex",
18
+ annotations: {
19
+ "pl7.app/label": "Read Index"
20
+ },
21
+ domain: {
22
+
23
+
24
+
25
+
26
+ "pl7.app/readIndices": string(json.encode(dataset.content.readIndices))
27
+ }
28
+ }
29
+
30
+ spec.axesSpec = [sampleIdAxis, readIndexAxisSpec]
31
+
32
+ data := pColumn.resourceMapBuilder(2)
33
+ for sampleId, fileGroup in dataset.content.data {
34
+ for _, readIndex in dataset.content.readIndices {
35
+ importHandle := fileGroup[readIndex]
36
+ if !importHandle {
37
+ ll.panic("File handle not set for %v in sample %v", readIndex, sampleId)
38
+ }
39
+ data.add([sampleId, readIndex], importFile(importHandle))
40
+ }
41
+ }
42
+
43
+ result := {}
44
+ result["dataset." + dataset.id] = {
45
+ spec: spec,
46
+ data: data.build()
47
+ }
48
+
49
+ return result
50
+ }
51
+ }
@@ -0,0 +1,61 @@
1
+
2
+ ll := import("@platforma-sdk/workflow-tengo:ll")
3
+ pColumn := import("@platforma-sdk/workflow-tengo:pframes.pcolumn")
4
+ json := import("json")
5
+ util := import("@platforma-open/milaboratories.samples-and-data.workflow:util")
6
+
7
+ export {
8
+ isGrouped: false,
9
+
10
+ createDataset: func(blockId, sampleIdAxis, dataset, importFile) {
11
+ extension := dataset.content.gzipped ? "fastq.gz" : "fastq"
12
+
13
+ spec := util.datasetColumnSpecBase(blockId, dataset, extension)
14
+
15
+ laneAxisSpec := {
16
+ type: "String",
17
+ name: "pl7.app/sequencing/lane",
18
+ annotations: {
19
+ "pl7.app/label": "Lane"
20
+ }
21
+ }
22
+
23
+ readIndexAxisSpec := {
24
+ type: "String",
25
+ name: "pl7.app/sequencing/readIndex",
26
+ annotations: {
27
+ "pl7.app/label": "Read Index"
28
+ },
29
+ domain: {
30
+
31
+
32
+
33
+
34
+ "pl7.app/readIndices": string(json.encode(dataset.content.readIndices))
35
+ }
36
+ }
37
+
38
+ spec.axesSpec = [sampleIdAxis, laneAxisSpec, readIndexAxisSpec]
39
+
40
+ data := pColumn.resourceMapBuilder(3)
41
+ for sampleId, laneData in dataset.content.data {
42
+ for laneId, fileGroup in laneData {
43
+ for _, readIndex in dataset.content.readIndices {
44
+ importHandle := fileGroup[readIndex]
45
+ if !importHandle {
46
+ ll.panic("File handle not set for %v, lane %v in sample %v", readIndex, laneId, sampleId)
47
+ }
48
+ data.add([sampleId, laneId, readIndex], importFile(importHandle))
49
+ }
50
+ }
51
+ }
52
+
53
+ result := {}
54
+ result["dataset." + dataset.id] = {
55
+ spec: spec,
56
+ data: data.build()
57
+ }
58
+
59
+ return result
60
+ }
61
+ }
@@ -0,0 +1,96 @@
1
+
2
+ ll := import("@platforma-sdk/workflow-tengo:ll")
3
+ pColumn := import("@platforma-sdk/workflow-tengo:pframes.pcolumn")
4
+ maps := import("@platforma-sdk/workflow-tengo:maps")
5
+ json := import("json")
6
+ util := import("@platforma-open/milaboratories.samples-and-data.workflow:util")
7
+
8
+ export {
9
+ isGrouped: false,
10
+
11
+ createDataset: func(blockId, sampleIdAxis, dataset, importFile) {
12
+ extension := dataset.content.gzipped ? "fastq.gz" : "fastq"
13
+
14
+ spec := util.datasetColumnSpecBase(blockId, dataset, extension)
15
+
16
+ axesSpec := [sampleIdAxis]
17
+
18
+ for tag in dataset.content.tags {
19
+ axesSpec = append(axesSpec, {
20
+ type: "String",
21
+ name: "pl7.app/sequencing/tag",
22
+ domain: {
23
+ "pl7.app/sequencing/tag": tag
24
+ },
25
+ annotations: {
26
+ "pl7.app/label": tag + " tag"
27
+ }
28
+ })
29
+ }
30
+
31
+ if dataset.content.hasLanes {
32
+ laneAxisSpec := {
33
+ type: "String",
34
+ name: "pl7.app/sequencing/lane",
35
+ annotations: {
36
+ "pl7.app/label": "Lane"
37
+ }
38
+ }
39
+
40
+ axesSpec = append(axesSpec, laneAxisSpec)
41
+ }
42
+
43
+ readIndexAxisSpec := {
44
+ type: "String",
45
+ name: "pl7.app/sequencing/readIndex",
46
+ annotations: {
47
+ "pl7.app/label": "Read Index"
48
+ },
49
+ domain: {
50
+
51
+
52
+
53
+
54
+ "pl7.app/readIndices": string(json.encode(dataset.content.readIndices))
55
+ }
56
+ }
57
+
58
+ axesSpec = append(axesSpec, readIndexAxisSpec)
59
+ spec.axesSpec = axesSpec
60
+
61
+ data := pColumn.resourceMapBuilder(len(axesSpec))
62
+
63
+ for sampleId, records in dataset.content.data {
64
+ for record in records {
65
+ keyPrefix := [sampleId]
66
+ for tag in dataset.content.tags {
67
+ tagValue := record.tags[tag]
68
+ if !tagValue {
69
+ ll.panic("No tag value for %v in sample %v", tag, sampleId)
70
+ }
71
+ keyPrefix = append(keyPrefix, tagValue)
72
+ }
73
+ if dataset.content.hasLanes {
74
+ keyPrefix = append(keyPrefix, record.lane)
75
+ }
76
+ for readIndex in dataset.content.readIndices {
77
+ importHandle := record.files[readIndex]
78
+ key := maps.clone(keyPrefix)
79
+ key = append(key, readIndex)
80
+ if !importHandle {
81
+ ll.panic("File handle not set for key %v", key)
82
+ }
83
+ data.add(key, importFile(importHandle))
84
+ }
85
+ }
86
+ }
87
+
88
+ result := {}
89
+ result["dataset." + dataset.id] = {
90
+ spec: spec,
91
+ data: data.build()
92
+ }
93
+
94
+ return result
95
+ }
96
+ }
@@ -0,0 +1,63 @@
1
+
2
+ ll := import("@platforma-sdk/workflow-tengo:ll")
3
+ pColumn := import("@platforma-sdk/workflow-tengo:pframes.pcolumn")
4
+ maps := import("@platforma-sdk/workflow-tengo:maps")
5
+
6
+ util := import("@platforma-open/milaboratories.samples-and-data.workflow:util")
7
+
8
+ export {
9
+ isGrouped: false,
10
+
11
+ createDataset: func(blockId, sampleIdAxis, dataset, importFile) {
12
+
13
+ extension := dataset.content.xsvType + (dataset.content.gzipped ? ".gz" : "")
14
+
15
+ spec := util.datasetColumnSpecBase(blockId, dataset, extension)
16
+
17
+ axesSpec := [sampleIdAxis]
18
+
19
+ for tag in dataset.content.tags {
20
+ axesSpec = append(axesSpec, {
21
+ type: "String",
22
+ name: "pl7.app/sequencing/tag",
23
+ domain: {
24
+ "pl7.app/sequencing/tag": tag
25
+ },
26
+ annotations: {
27
+ "pl7.app/label": tag + " tag"
28
+ }
29
+ })
30
+ }
31
+
32
+ spec.axesSpec = axesSpec
33
+
34
+ data := pColumn.resourceMapBuilder(len(axesSpec))
35
+
36
+ for sampleId, records in dataset.content.data {
37
+ for record in records {
38
+ key := [sampleId]
39
+ for tag in dataset.content.tags {
40
+ tagValue := record.tags[tag]
41
+ if !tagValue {
42
+ ll.panic("No tag value for %v in sample %v", tag, sampleId)
43
+ }
44
+ key = append(key, tagValue)
45
+ }
46
+
47
+ importHandle := record.file
48
+ if !importHandle {
49
+ ll.panic("File handle not set for key %v", key)
50
+ }
51
+ data.add(key, importFile(importHandle))
52
+ }
53
+ }
54
+
55
+ result := {}
56
+ result["dataset." + dataset.id] = {
57
+ spec: spec,
58
+ data: data.build()
59
+ }
60
+
61
+ return result
62
+ }
63
+ }
@@ -0,0 +1,33 @@
1
+
2
+ ll := import("@platforma-sdk/workflow-tengo:ll")
3
+ pColumn := import("@platforma-sdk/workflow-tengo:pframes.pcolumn")
4
+
5
+ util := import("@platforma-open/milaboratories.samples-and-data.workflow:util")
6
+
7
+ export {
8
+ isGrouped: false,
9
+
10
+ createDataset: func(blockId, sampleIdAxis, dataset, importFile) {
11
+
12
+ extension := dataset.content.xsvType + (dataset.content.gzipped ? ".gz" : "")
13
+
14
+ spec := util.datasetColumnSpecBase(blockId, dataset, extension)
15
+ spec.axesSpec = [sampleIdAxis]
16
+
17
+ data := pColumn.resourceMapBuilder(1)
18
+ for sampleId, importHandle in dataset.content.data {
19
+ if !importHandle {
20
+ ll.panic("File handle not set for sample %v", sampleId)
21
+ }
22
+ data.add([sampleId], importFile(importHandle))
23
+ }
24
+
25
+ result := {}
26
+ result["dataset." + dataset.id] = {
27
+ spec: spec,
28
+ data: data.build()
29
+ }
30
+
31
+ return result
32
+ }
33
+ }
@@ -0,0 +1,63 @@
1
+
2
+ ll := import("@platforma-sdk/workflow-tengo:ll")
3
+ json := import("json")
4
+ util := import("@platforma-open/milaboratories.samples-and-data.workflow:util")
5
+
6
+
7
+ normalizeString := func(str) {
8
+ return str
9
+ }
10
+
11
+
12
+
13
+
14
+
15
+
16
+
17
+
18
+
19
+
20
+ createMetadata := func(args, blockId, sampleIdAxisSpec) {
21
+ columns := {}
22
+ for _, column in args.metadata {
23
+ columns["metadata." + column.id] = {
24
+ spec: {
25
+ kind: "PColumn",
26
+ name: "pl7.app/metadata",
27
+ valueType: column.valueType,
28
+ annotations: {
29
+ "pl7.app/label": column.label
30
+ },
31
+ domain: {
32
+ "pl7.app/columnId": column.global ? normalizeString(column.label) : column.id
33
+ },
34
+ axesSpec: [sampleIdAxisSpec]
35
+ },
36
+ data: util.createJsonPColumnData(column.data)
37
+ }
38
+ }
39
+
40
+
41
+
42
+
43
+
44
+ columns["metadata.sampleId"] = {
45
+ spec: {
46
+ kind: "PColumn",
47
+ name: "pl7.app/label",
48
+ valueType: "String",
49
+ annotations: {
50
+ "pl7.app/label": args.sampleLabelColumnLabel,
51
+ "pl7.app/isLabel": "true"
52
+ },
53
+ axesSpec: [sampleIdAxisSpec]
54
+ },
55
+ data: util.createJsonPColumnData(args.sampleLabels)
56
+ }
57
+
58
+ return columns
59
+ }
60
+
61
+ export {
62
+ createMetadata: createMetadata
63
+ }
@@ -0,0 +1,80 @@
1
+ json := import("json")
2
+ maps := import("@platforma-sdk/workflow-tengo:maps")
3
+ smart := import("@platforma-sdk/workflow-tengo:smart")
4
+ consts := import("@platforma-sdk/workflow-tengo:pframes.constants")
5
+
6
+ RTYPE_P_COLUMN_DATA_JSON := consts.RTYPE_P_COLUMN_DATA_JSON
7
+
8
+ mapToPValueData := func(map) {
9
+ data := {}
10
+ for key, value in map {
11
+ data[json.encode([key])] = value
12
+ }
13
+ result := {
14
+ keyLength: 1,
15
+ data: data
16
+ }
17
+ return result
18
+ }
19
+
20
+ createJsonPColumnData := func(data) {
21
+ return smart.createValueResource(RTYPE_P_COLUMN_DATA_JSON, json.encode(mapToPValueData(data)))
22
+ }
23
+
24
+ datasetColumnSpecBase := func(blockId, dataset, extension) {
25
+ return {
26
+ kind: "PColumn",
27
+ name: "pl7.app/sequencing/data",
28
+ domain: maps.clone({
29
+ "pl7.app/fileExtension": extension,
30
+ "pl7.app/block": blockId,
31
+ "pl7.app/dataset": dataset.id
32
+ }, { removeUndefs: true }),
33
+ valueType: "File",
34
+ annotations: {
35
+ "pl7.app/label": "Sequencing Data",
36
+ "pl7.app/hideDataFromUi": "true",
37
+ "pl7.app/axisKeys/0": string(json.encode(maps.getKeys(dataset.content.data))) // axis values for sampleIdAxis or groupIdAxis
38
+ }
39
+ }
40
+ }
41
+
42
+ sampleGroupsLinkerColumn := func(blockId, dataset, sampleIdAxis, groupIdAxis) {
43
+ data := {}
44
+ samples := []
45
+ for groupId, ss in dataset.content.sampleGroups {
46
+ for sampleId, sampleName in ss {
47
+ samples = samples + [sampleId]
48
+ data[json.encode([groupId, sampleId])] = sampleName
49
+ }
50
+ }
51
+ spec := {
52
+ kind: "PColumn",
53
+ name: "pl7.app/sequencing/data/sampleGroups",
54
+ domain: {
55
+ "pl7.app/block": blockId,
56
+ "pl7.app/dataset": dataset.id
57
+ },
58
+ valueType: "String",
59
+ axesSpec: [groupIdAxis, sampleIdAxis],
60
+ annotations: {
61
+ "pl7.app/label": "Sample Groups",
62
+ "pl7.app/isLinkedColumn": "true",
63
+ "pl7.app/hideDataFromUi": "true",
64
+ "pl7.app/axisKeys/0": string(json.encode(maps.getKeys(dataset.content.data))), // axis values for groupIdAxis
65
+ "pl7.app/axisKeys/1": string(json.encode(samples)) // axis values for sampleIdAxis
66
+ }
67
+ }
68
+
69
+ return {
70
+ spec: spec,
71
+ data: smart.createValueResource(RTYPE_P_COLUMN_DATA_JSON, json.encode(data))
72
+ }
73
+ }
74
+
75
+
76
+ export {
77
+ createJsonPColumnData: createJsonPColumnData,
78
+ datasetColumnSpecBase: datasetColumnSpecBase,
79
+ sampleGroupsLinkerColumn: sampleGroupsLinkerColumn
80
+ }
Binary file
Binary file
package/package.json CHANGED
@@ -1,16 +1,16 @@
1
1
  {
2
2
  "name": "@platforma-open/milaboratories.samples-and-data.workflow",
3
- "version": "1.13.2",
3
+ "version": "2.0.0",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "./dist/**/*"
7
7
  ],
8
8
  "description": "Tengo-based template",
9
9
  "dependencies": {
10
- "@platforma-sdk/workflow-tengo": "^5.2.0"
10
+ "@platforma-sdk/workflow-tengo": "^5.4.5"
11
11
  },
12
12
  "devDependencies": {
13
- "@platforma-sdk/tengo-builder": "^2.1.13"
13
+ "@platforma-sdk/tengo-builder": "^2.3.2"
14
14
  },
15
15
  "scripts": {
16
16
  "build": "rm -rf dist/* && pl-tengo check && pl-tengo build",