@platforma-open/milaboratories.mixcr-clonotyping-2.workflow 3.16.0 → 3.17.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,6 +1,6 @@
1
1
   WARN  Issue while reading "/home/runner/work/mixcr-clonotyping/mixcr-clonotyping/.npmrc". Failed to replace env in config: ${NPMJS_TOKEN}
2
2
 
3
- > @platforma-open/milaboratories.mixcr-clonotyping-2.workflow@3.16.0 build /home/runner/work/mixcr-clonotyping/mixcr-clonotyping/workflow
3
+ > @platforma-open/milaboratories.mixcr-clonotyping-2.workflow@3.17.1 build /home/runner/work/mixcr-clonotyping/mixcr-clonotyping/workflow
4
4
  > rm -rf dist && pl-tengo check && pl-tengo build
5
5
 
6
6
  info: Skipping unknown file type: test/columns.test.ts
package/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # @platforma-open/milaboratories.mixcr-clonotyping.workflow
2
2
 
3
+ ## 3.17.1
4
+
5
+ ### Patch Changes
6
+
7
+ - 5d90233: Hide non-relevant columns
8
+
9
+ ## 3.17.0
10
+
11
+ ### Minor Changes
12
+
13
+ - 480dfc5: generic presets added
14
+
3
15
  ## 3.16.0
4
16
 
5
17
  ### Minor Changes
@@ -73,6 +73,9 @@ assemblingFeatureInfo := func(assemblingFeature) {
73
73
  } else if len(splittedFeature2) == 2 {
74
74
  if splittedFeature2[0] == "{CDR3Begin" {
75
75
  productiveFeature = assemblingFeature
76
+ } else if splittedFeature2[0] == "{FR3Begin" {
77
+ productiveFeature = assemblingFeature
78
+ coreVFeature = "FR3"
76
79
  } else {
77
80
  productiveFeature = assemblingFeature
78
81
  coreVFeature = splittedFeature2[0]+":FR3End}"
@@ -257,13 +260,14 @@ calculateExportSpecs := func(presetSpecForBack, sampleIdAxisSpec, blockId) {
257
260
  spec: {
258
261
  name: "pl7.app/vdj/readFractionMean",
259
262
  valueType: "Double",
260
- annotations: a(87130, true, {
263
+ annotations: a(87130, false, {
261
264
  "pl7.app/min": "0",
262
265
  "pl7.app/max": "1",
263
266
  "pl7.app/isAbundance": "true",
264
267
  "pl7.app/abundance/unit": "reads",
265
268
  "pl7.app/abundance/normalized": "true",
266
269
  "pl7.app/label": "Mean Fraction of Reads",
270
+ "pl7.app/description": "The average read fraction of a clonotype across all samples where it is present.",
267
271
  "pl7.app/format": ".2p"
268
272
  })
269
273
  }
@@ -338,13 +342,14 @@ calculateExportSpecs := func(presetSpecForBack, sampleIdAxisSpec, blockId) {
338
342
  spec: {
339
343
  name: "pl7.app/vdj/uniqueMoleculeFractionMean",
340
344
  valueType: "Double",
341
- annotations: a(87130, true, {
345
+ annotations: a(87130, false, {
342
346
  "pl7.app/min": "0",
343
347
  "pl7.app/max": "1",
344
348
  "pl7.app/isAbundance": "true",
345
349
  "pl7.app/abundance/unit": "molecules",
346
350
  "pl7.app/abundance/normalized": "true",
347
351
  "pl7.app/label": "Mean Fraction of UMIs",
352
+ "pl7.app/description": "The average UMI fraction of a clonotype across all samples where it is present.",
348
353
  "pl7.app/format": ".2p"
349
354
  })
350
355
  }
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
package/package.json CHANGED
@@ -1,15 +1,15 @@
1
1
  {
2
2
  "name": "@platforma-open/milaboratories.mixcr-clonotyping-2.workflow",
3
- "version": "3.16.0",
3
+ "version": "3.17.1",
4
4
  "description": "Tengo-based template",
5
5
  "dependencies": {
6
- "@platforma-sdk/workflow-tengo": "^5.6.5",
6
+ "@platforma-sdk/workflow-tengo": "^5.6.6",
7
7
  "@platforma-open/milaboratories.software-mixcr": "4.7.0-254-develop"
8
8
  },
9
9
  "devDependencies": {
10
- "@milaboratories/ts-configs": "^1.0.6",
11
- "@platforma-sdk/tengo-builder": "^2.3.14",
12
- "@platforma-sdk/test": "^1.46.5",
10
+ "@milaboratories/ts-configs": "^1.1.0",
11
+ "@platforma-sdk/tengo-builder": "^2.4.1",
12
+ "@platforma-sdk/test": "^1.47.6",
13
13
  "vitest": "~4.0.15",
14
14
  "typescript": "~5.6.3"
15
15
  },
@@ -73,6 +73,9 @@ assemblingFeatureInfo := func(assemblingFeature) {
73
73
  } else if len(splittedFeature2) == 2 {
74
74
  if splittedFeature2[0] == "{CDR3Begin" {
75
75
  productiveFeature = assemblingFeature
76
+ } else if splittedFeature2[0] == "{FR3Begin" {
77
+ productiveFeature = assemblingFeature
78
+ coreVFeature = "FR3"
76
79
  } else {
77
80
  productiveFeature = assemblingFeature
78
81
  coreVFeature = splittedFeature2[0]+":FR3End}"
@@ -257,13 +260,14 @@ calculateExportSpecs := func(presetSpecForBack, sampleIdAxisSpec, blockId) {
257
260
  spec: {
258
261
  name: "pl7.app/vdj/readFractionMean",
259
262
  valueType: "Double",
260
- annotations: a(87130, true, {
263
+ annotations: a(87130, false, {
261
264
  "pl7.app/min": "0",
262
265
  "pl7.app/max": "1",
263
266
  "pl7.app/isAbundance": "true",
264
267
  "pl7.app/abundance/unit": "reads",
265
268
  "pl7.app/abundance/normalized": "true",
266
269
  "pl7.app/label": "Mean Fraction of Reads",
270
+ "pl7.app/description": "The average read fraction of a clonotype across all samples where it is present.",
267
271
  "pl7.app/format": ".2p"
268
272
  })
269
273
  }
@@ -338,13 +342,14 @@ calculateExportSpecs := func(presetSpecForBack, sampleIdAxisSpec, blockId) {
338
342
  spec: {
339
343
  name: "pl7.app/vdj/uniqueMoleculeFractionMean",
340
344
  valueType: "Double",
341
- annotations: a(87130, true, {
345
+ annotations: a(87130, false, {
342
346
  "pl7.app/min": "0",
343
347
  "pl7.app/max": "1",
344
348
  "pl7.app/isAbundance": "true",
345
349
  "pl7.app/abundance/unit": "molecules",
346
350
  "pl7.app/abundance/normalized": "true",
347
351
  "pl7.app/label": "Mean Fraction of UMIs",
352
+ "pl7.app/description": "The average UMI fraction of a clonotype across all samples where it is present.",
348
353
  "pl7.app/format": ".2p"
349
354
  })
350
355
  }
@@ -11,7 +11,12 @@ self.validateInputs({
11
11
  preset: "any",
12
12
  params: {
13
13
  "__options__,closed": "",
14
- "species,omitempty": "string"
14
+ "species,omitempty": "string",
15
+ "leftAlignmentMode,omitempty": "string",
16
+ "rightAlignmentMode,omitempty": "string",
17
+ "materialType,omitempty": "string",
18
+ "tagPattern,omitempty": "string",
19
+ "assembleClonesBy,omitempty": "string"
15
20
  }
16
21
  })
17
22
 
@@ -22,6 +27,11 @@ self.defineOutputs("preset", "presetSpecForBack")
22
27
  self.body(func(inputs) {
23
28
  preset := inputs.preset
24
29
  species := inputs.params.species
30
+ leftAlignmentMode := inputs.params.leftAlignmentMode
31
+ rightAlignmentMode := inputs.params.rightAlignmentMode
32
+ materialType := inputs.params.materialType
33
+ tagPattern := inputs.params.tagPattern
34
+ assembleClonesBy := inputs.params.assembleClonesBy
25
35
 
26
36
  mixcrExportPresetCmdBuilder := exec.builder().
27
37
  inLightQueue().
@@ -47,6 +57,22 @@ self.body(func(inputs) {
47
57
  mixcrExportPresetCmdBuilder.arg("--species").arg(species)
48
58
  }
49
59
 
60
+ if !is_undefined(leftAlignmentMode) {
61
+ mixcrExportPresetCmdBuilder.arg(leftAlignmentMode)
62
+ }
63
+ if !is_undefined(rightAlignmentMode) {
64
+ mixcrExportPresetCmdBuilder.arg(rightAlignmentMode)
65
+ }
66
+ if !is_undefined(materialType) {
67
+ mixcrExportPresetCmdBuilder.arg(materialType)
68
+ }
69
+ if !is_undefined(tagPattern) {
70
+ mixcrExportPresetCmdBuilder.arg("--tag-pattern").arg(tagPattern)
71
+ }
72
+ if !is_undefined(assembleClonesBy) {
73
+ mixcrExportPresetCmdBuilder.arg("--assemble-clonotypes-by").arg(assembleClonesBy)
74
+ }
75
+
50
76
  mixcrExportPresetCmd := mixcrExportPresetCmdBuilder.arg("preset.json").
51
77
  saveFileContent("preset.json").
52
78
  saveFile("preset.json").
@@ -86,7 +86,12 @@ wf.body(func(args) {
86
86
  presetInfoResult := render.create(calculatePresetInfoTpl, {
87
87
  preset: presetResource,
88
88
  params: {
89
- species: species
89
+ species: species,
90
+ leftAlignmentMode: args.leftAlignmentMode,
91
+ rightAlignmentMode: args.rightAlignmentMode,
92
+ materialType: args.materialType,
93
+ tagPattern: args.tagPattern,
94
+ assembleClonesBy: args.assembleClonesBy
90
95
  }
91
96
  })
92
97
 
@@ -111,7 +116,7 @@ wf.body(func(args) {
111
116
 
112
117
  library: library,
113
118
 
114
- params: smart.createJsonResource({
119
+ params: smart.createJsonResource({
115
120
  species: species,
116
121
  receptorsOrChains: receptorsOrChains,
117
122
  limitInput: limitInput,
@@ -121,7 +126,12 @@ wf.body(func(args) {
121
126
  blockId: blockId,
122
127
  libraryId: libraryId,
123
128
  presetCommonName: args.presetCommonName,
124
- isLibraryFileGzipped: isLibraryFileGzipped
129
+ isLibraryFileGzipped: isLibraryFileGzipped,
130
+ leftAlignmentMode: args.leftAlignmentMode,
131
+ rightAlignmentMode: args.rightAlignmentMode,
132
+ materialType: args.materialType,
133
+ tagPattern: args.tagPattern,
134
+ assembleClonesBy: args.assembleClonesBy
125
135
  })
126
136
  })
127
137
 
@@ -29,6 +29,11 @@ self.body(func(inputs) {
29
29
  params := inputs.params
30
30
  species := params.species
31
31
  limitInput := params.limitInput
32
+ leftAlignmentMode := params.leftAlignmentMode
33
+ rightAlignmentMode := params.rightAlignmentMode
34
+ materialType := params.materialType
35
+ tagPattern := params.tagPattern
36
+ assembleClonesBy := params.assembleClonesBy
32
37
  perProcessMemGB := inputs.perProcessMemGB
33
38
  perProcessCPUs := inputs.perProcessCPUs
34
39
  fileExtension := params.fileExtension
@@ -122,6 +127,22 @@ self.body(func(inputs) {
122
127
  arg(preset.name)
123
128
  }
124
129
 
130
+ // Optional preset-specific parameters (order matters if preset requires positional values)
131
+ if !is_undefined(leftAlignmentMode) {
132
+ mixcrCmdBuilder.arg(leftAlignmentMode)
133
+ }
134
+ if !is_undefined(rightAlignmentMode) {
135
+ mixcrCmdBuilder.arg(rightAlignmentMode)
136
+ }
137
+ if !is_undefined(materialType) {
138
+ mixcrCmdBuilder.arg(materialType)
139
+ }
140
+ if !is_undefined(tagPattern) {
141
+ mixcrCmdBuilder.arg("--tag-pattern").arg(tagPattern)
142
+ }
143
+ if !is_undefined(assembleClonesBy) {
144
+ mixcrCmdBuilder.arg("--assemble-clonotypes-by").arg(assembleClonesBy)
145
+ }
125
146
  // High diversity library tuning
126
147
  highDiversityLibrary := params.highDiversityLibrary
127
148
  if !is_undefined(highDiversityLibrary) && highDiversityLibrary {
@@ -49,10 +49,16 @@ wf.body(func(args) {
49
49
  ll.assert(preset.type == "name", "unexpected preset type")
50
50
  // whole json, including type
51
51
  presetResource = smart.createJsonResource(preset)
52
+ isGenericPreset := args.isGenericPreset
52
53
  presetInfoResult := render.create(calculatePresetInfoTpl, {
53
54
  preset: presetResource,
54
55
  params: {
55
- species: args.species
56
+ species: args.species,
57
+ leftAlignmentMode: args.leftAlignmentMode,
58
+ rightAlignmentMode: args.rightAlignmentMode,
59
+ materialType: args.materialType,
60
+ tagPattern: isGenericPreset ? "^(R1:*)\\^(R2:*)" : undefined,
61
+ assembleClonesBy: isGenericPreset ? "CDR3" : undefined
56
62
  }
57
63
  })
58
64
  outputs.preset = presetInfoResult.output("presetSpecForBack", 24 * 60 * 60 * 1000)
@@ -268,6 +268,11 @@ self.body(func(inputs) {
268
268
  fileExtension: fileExtension,
269
269
  reports: reports,
270
270
  isLibraryFileGzipped: isLibraryFileGzipped,
271
+ leftAlignmentMode: params.leftAlignmentMode,
272
+ rightAlignmentMode: params.rightAlignmentMode,
273
+ materialType: params.materialType,
274
+ tagPattern: params.tagPattern,
275
+ assembleClonesBy: params.assembleClonesBy,
271
276
  highDiversityLibrary: params.highDiversityLibrary
272
277
  },
273
278
  library: library,
@@ -452,12 +457,35 @@ self.body(func(inputs) {
452
457
  } ]
453
458
 
454
459
  if !isSingleCell {
460
+ // Modify column visibility for TCR chains
461
+ isTCRChain := text.has_prefix(chain, "TCR")
462
+ columnsForAggregation := columnsSpecPerClonotypeNoAggregates + columnsSpecPerClonotypeAggregates
463
+ if isTCRChain {
464
+ visibilitySettings := {
465
+ "bestCGene": "optional",
466
+ "bestCHit": "optional",
467
+ "isotypePrimary": "hidden"
468
+ }
469
+ columnsForAggregation = slices.map(columnsForAggregation, func(col) {
470
+ visibility := visibilitySettings[col.column]
471
+ if !is_undefined(visibility) {
472
+ return maps.deepMerge(col, {
473
+ spec: {
474
+ annotations: maps.merge(col.spec.annotations, {
475
+ "pl7.app/table/visibility": visibility
476
+ })
477
+ }
478
+ })
479
+ }
480
+ return col
481
+ })
482
+ }
455
483
  aggregationOutputs += [ {
456
484
  type: "Xsv",
457
485
  xsvType: "tsv",
458
486
  settings: {
459
487
  axes: [ axisByClonotypeKeyGen(chain) ],
460
- columns: columnsSpecPerClonotypeNoAggregates + columnsSpecPerClonotypeAggregates,
488
+ columns: columnsForAggregation,
461
489
  storageFormat: "Parquet",
462
490
  partitionKeyLength: 0
463
491
  },
@@ -583,9 +611,34 @@ self.body(func(inputs) {
583
611
  for chainIdx in [0, 1] {
584
612
  // "A" chain is always the one that is more diverse
585
613
  chainLetterU := ["A", "B"][chainIdx]
586
- chainNameU := chainInfos[receptorInfo.chains[chainIdx]].shortName
614
+ chain := receptorInfo.chains[chainIdx]
615
+ chainNameU := chainInfos[chain].shortName
587
616
  chainNameL := text.to_lower(chainNameU)
588
617
 
618
+ // Modify column visibility for TCR chains
619
+ isTCRChain := text.has_prefix(chain, "TCR")
620
+ columnsForSingleCell := columnsSpecPerClonotypeNoAggregates
621
+ if isTCRChain {
622
+ visibilitySettings := {
623
+ "bestCGene": "optional",
624
+ "bestCHit": "optional",
625
+ "isotypePrimary": "hidden"
626
+ }
627
+ columnsForSingleCell = slices.map(columnsForSingleCell, func(col) {
628
+ visibility := visibilitySettings[col.column]
629
+ if !is_undefined(visibility) {
630
+ return maps.deepMerge(col, {
631
+ spec: {
632
+ annotations: maps.merge(col.spec.annotations, {
633
+ "pl7.app/table/visibility": visibility
634
+ })
635
+ }
636
+ })
637
+ }
638
+ return col
639
+ })
640
+ }
641
+
589
642
  for isPrimary in [true, false] {
590
643
  pPrefixU := isPrimary ? "Primary" : "Secondary"
591
644
  pPrefixL := text.to_lower(pPrefixU)
@@ -625,7 +678,7 @@ self.body(func(inputs) {
625
678
  xsvType: "tsv",
626
679
  settings: {
627
680
  axes: [ axisByScClonotypeKeyGen(receptor) ],
628
- columns: transformSpecs(isPrimary ? columnsSpecPerClonotypeNoAggregates : columnsSpecPerClonotypeSecondary, {
681
+ columns: transformSpecs(isPrimary ? columnsForSingleCell : columnsSpecPerClonotypeSecondary, {
629
682
  spec: {
630
683
  domain: {
631
684
  "pl7.app/vdj/scClonotypeChain": chainLetterU,