@platforma-open/milaboratories.tcrdisco-enrichment.workflow 1.1.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/.turbo/turbo-build.log +27 -0
- package/CHANGELOG.md +12 -0
- package/dist/index.cjs +5 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +6 -0
- package/dist/tengo/lib/libs.cd_subset_params.lib.tengo +42 -0
- package/dist/tengo/lib/libs.tcr_pairs_params.lib.tengo +159 -0
- package/dist/tengo/lib/libs.tcrdisco_da_pfconv_params.lib.tengo +54 -0
- package/dist/tengo/lib/libs.top_frequencies.lib.tengo +46 -0
- package/dist/tengo/lib/libs.top_table_pfconv_params.lib.tengo +238 -0
- package/dist/tengo/tpl/main.plj.gz +0 -0
- package/dist/tengo/tpl/tcr-ab-pairs.plj.gz +0 -0
- package/dist/tengo/tpl/tcr-analysis.plj.gz +0 -0
- package/format.el +43 -0
- package/index.d.ts +4 -0
- package/index.js +3 -0
- package/package.json +20 -0
- package/src/libs/cd_subset_params.lib.tengo +42 -0
- package/src/libs/tcr_pairs_params.lib.tengo +159 -0
- package/src/libs/tcrdisco_da_pfconv_params.lib.tengo +54 -0
- package/src/libs/top_frequencies.lib.tengo +46 -0
- package/src/libs/top_table_pfconv_params.lib.tengo +238 -0
- package/src/main.tpl.tengo +579 -0
- package/src/tcr-ab-pairs.tpl.tengo +60 -0
- package/src/tcr-analysis.tpl.tengo +226 -0
- package/src/wf.test.ts +13 -0
- package/tsconfig.json +16 -0
- package/vitest.config.mts +9 -0
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
self := import("@platforma-sdk/workflow-tengo:tpl")
|
|
2
|
+
exec := import("@platforma-sdk/workflow-tengo:exec")
|
|
3
|
+
assets := import("@platforma-sdk/workflow-tengo:assets")
|
|
4
|
+
pt := import("@platforma-sdk/workflow-tengo:pt")
|
|
5
|
+
xsv := import("@platforma-sdk/workflow-tengo:pframes.xsv")
|
|
6
|
+
pframes := import("@platforma-sdk/workflow-tengo:pframes")
|
|
7
|
+
pSpec := import("@platforma-sdk/workflow-tengo:pframes.spec")
|
|
8
|
+
smart := import("@platforma-sdk/workflow-tengo:smart")
|
|
9
|
+
text := import("text")
|
|
10
|
+
json := import("json")
|
|
11
|
+
|
|
12
|
+
subsetAssignment := assets.importSoftware("@platforma-open/milaboratories.run-tcrdisco-enrichment.software:subset-assignment")
|
|
13
|
+
diffSoftware := assets.importSoftware("@platforma-open/milaboratories.run-tcrdisco-enrichment.software:tcr-disco")
|
|
14
|
+
getEnrichedFrequenciesSoftware := assets.importSoftware("@platforma-open/milaboratories.run-tcrdisco-enrichment.software:get-enriched-frequencies")
|
|
15
|
+
tcrdiscoDaPfconvParamsLib := import(":libs.tcrdisco_da_pfconv_params")
|
|
16
|
+
self.validateInputs({
|
|
17
|
+
"__options__,closed": "",
|
|
18
|
+
"numerators": "any",
|
|
19
|
+
"denominators": "any",
|
|
20
|
+
"mainAlphaTsv": "any",
|
|
21
|
+
"mainBetaTsv": "any",
|
|
22
|
+
"metadataTsv": "any",
|
|
23
|
+
"cdAlphaTsv,?": "any",
|
|
24
|
+
"cdBetaTsv,?": "any",
|
|
25
|
+
"cdMetadataTsv,?": "any",
|
|
26
|
+
"cdSubsetCol,?": "string",
|
|
27
|
+
"covariatesTsv": "any",
|
|
28
|
+
"contrastColLabel": "string",
|
|
29
|
+
"thresholdCounts": "number",
|
|
30
|
+
"thresholdSamples": "number",
|
|
31
|
+
"log2FcThreshold": "number",
|
|
32
|
+
"pAdjThreshold": "number",
|
|
33
|
+
"mainAlphaSpec,?": "any",
|
|
34
|
+
"mainBetaSpec,?": "any",
|
|
35
|
+
"blockId,?": "string",
|
|
36
|
+
"defaultConvMem,?": "string",
|
|
37
|
+
"defaultConvCpu,?": "number"
|
|
38
|
+
})
|
|
39
|
+
|
|
40
|
+
self.defineOutputs("topTableFileAlpha","topTableFileBeta","daFileAlpha",
|
|
41
|
+
"daFileBeta","contrastMap","mainAlphaFrequenciesTsv","mainBetaFrequenciesTsv",
|
|
42
|
+
"clonotypeToSubsetAlpha","clonotypeToSubsetBeta",
|
|
43
|
+
"robustEnrichmentPFAlpha_clonotype","robustEnrichmentPFBeta_clonotype")
|
|
44
|
+
|
|
45
|
+
self.body(func(inputs) {
|
|
46
|
+
|
|
47
|
+
denominators := inputs.denominators
|
|
48
|
+
denominatorString := text.join(denominators, "-")
|
|
49
|
+
covariatesTsv := inputs.covariatesTsv
|
|
50
|
+
contrastColLabel := inputs.contrastColLabel
|
|
51
|
+
thresholdCounts := inputs.thresholdCounts
|
|
52
|
+
thresholdSamples := inputs.thresholdSamples
|
|
53
|
+
log2FcThreshold := inputs.log2FcThreshold
|
|
54
|
+
pAdjThreshold := inputs.pAdjThreshold
|
|
55
|
+
|
|
56
|
+
mainAlphaTsv := undefined
|
|
57
|
+
mainBetaTsv := undefined
|
|
58
|
+
// Assign CD4/CD8 subsets to main data and QC the input files
|
|
59
|
+
builder := exec.builder().
|
|
60
|
+
software(subsetAssignment).
|
|
61
|
+
addFile("mainAlpha.tsv", inputs.mainAlphaTsv).
|
|
62
|
+
addFile("mainBeta.tsv", inputs.mainBetaTsv).
|
|
63
|
+
addFile("metadata.tsv", inputs.metadataTsv).
|
|
64
|
+
arg("--main_alpha").arg("mainAlpha.tsv").
|
|
65
|
+
arg("--main_beta").arg("mainBeta.tsv").
|
|
66
|
+
arg("--metadata").arg("metadata.tsv").
|
|
67
|
+
arg("-o").arg(".").
|
|
68
|
+
saveFile("main_alpha_table.tsv").
|
|
69
|
+
saveFile("main_beta_table.tsv")
|
|
70
|
+
if !is_undefined(inputs.cdAlphaTsv) && !is_undefined(inputs.cdBetaTsv) {
|
|
71
|
+
builder.
|
|
72
|
+
addFile("cdAlpha.tsv", inputs.cdAlphaTsv).
|
|
73
|
+
addFile("cdBeta.tsv", inputs.cdBetaTsv).
|
|
74
|
+
arg("--cd_alpha").arg("cdAlpha.tsv").
|
|
75
|
+
arg("--cd_beta").arg("cdBeta.tsv").
|
|
76
|
+
arg("--cd_subset_col").arg(inputs.cdSubsetCol)
|
|
77
|
+
}
|
|
78
|
+
builder = builder.run()
|
|
79
|
+
|
|
80
|
+
// Stored main tables with/out subset information and after QC for samples
|
|
81
|
+
// with both alpha and beta chains (we keep only the most frequent one)
|
|
82
|
+
mainAlphaTsv = builder.getFile("main_alpha_table.tsv")
|
|
83
|
+
mainBetaTsv = builder.getFile("main_beta_table.tsv")
|
|
84
|
+
|
|
85
|
+
// run differential analysis per numerator
|
|
86
|
+
wf := pt.workflow().cpu(1).mem("2GiB")
|
|
87
|
+
dfsDegAlpha := []
|
|
88
|
+
dfsDegBeta := []
|
|
89
|
+
dfsTopTableAlpha := []
|
|
90
|
+
dfsTopTableBeta := []
|
|
91
|
+
contrastMap := {}
|
|
92
|
+
|
|
93
|
+
// Format 2 specs (with contrast in domain) - process outside workflow
|
|
94
|
+
degPframeBuilderAlpha_clonotype := pframes.pFrameBuilder()
|
|
95
|
+
degPframeBuilderBeta_clonotype := pframes.pFrameBuilder()
|
|
96
|
+
regDirPframeBuilderAlpha_clonotype := pframes.pFrameBuilder()
|
|
97
|
+
regDirPframeBuilderBeta_clonotype := pframes.pFrameBuilder()
|
|
98
|
+
robustEnrichmentPframeBuilderAlpha_clonotype := pframes.pFrameBuilder()
|
|
99
|
+
robustEnrichmentPframeBuilderBeta_clonotype := pframes.pFrameBuilder()
|
|
100
|
+
|
|
101
|
+
// Create trace if specs are provided
|
|
102
|
+
trace := undefined
|
|
103
|
+
if !is_undefined(inputs.mainAlphaSpec) {
|
|
104
|
+
trace = pSpec.makeTrace(inputs.mainAlphaSpec,
|
|
105
|
+
{type: "milaboratories.tcr-disco-enrichment", importance: 30,
|
|
106
|
+
label: "DA - Denominator: " + denominatorString + " (log2FC: " + log2FcThreshold + ", pAdj: " + pAdjThreshold + ")"}
|
|
107
|
+
)
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
diffExec := exec.builder().
|
|
111
|
+
software(diffSoftware).
|
|
112
|
+
addFile("mainAlpha.tsv", mainAlphaTsv).
|
|
113
|
+
addFile("mainBeta.tsv", mainBetaTsv).
|
|
114
|
+
addFile("covariates.tsv", covariatesTsv).
|
|
115
|
+
arg("--main_alpha").arg("mainAlpha.tsv").
|
|
116
|
+
arg("--main_beta").arg("mainBeta.tsv").
|
|
117
|
+
arg("--covariates").arg("covariates.tsv").
|
|
118
|
+
arg("-t").arg(contrastColLabel).
|
|
119
|
+
arg("-n").arg(string(json.encode(inputs.numerators))).
|
|
120
|
+
arg("-d").arg(string(json.encode(denominators))).
|
|
121
|
+
arg("-f").arg(string(log2FcThreshold)).
|
|
122
|
+
arg("-p").arg(string(pAdjThreshold)).
|
|
123
|
+
arg("--threshold_counts").arg(string(thresholdCounts)).
|
|
124
|
+
arg("-s").arg(string(thresholdSamples)).
|
|
125
|
+
arg("-o").arg(".").
|
|
126
|
+
saveFile("DA_alpha.csv").
|
|
127
|
+
saveFile("topTable_alpha.csv").
|
|
128
|
+
saveFile("DA_beta.csv").
|
|
129
|
+
saveFile("topTable_beta.csv")
|
|
130
|
+
|
|
131
|
+
for numerator in inputs.numerators {
|
|
132
|
+
numerator = string(numerator)
|
|
133
|
+
contrastMap[numerator + " vs " + denominatorString] = numerator + " vs " + denominatorString
|
|
134
|
+
|
|
135
|
+
diffExec.saveFile("robust_enrichment_alpha_" + numerator + ".csv").
|
|
136
|
+
saveFile("robust_enrichment_beta_" + numerator + ".csv")
|
|
137
|
+
}
|
|
138
|
+
diffExec = diffExec.run()
|
|
139
|
+
|
|
140
|
+
// Process format 2 specs (with contrast in domain) if specs are provided
|
|
141
|
+
// Delete this part once filters in tcr-leads allow axis value selection
|
|
142
|
+
for numerator in inputs.numerators {
|
|
143
|
+
numerator = string(numerator)
|
|
144
|
+
if !is_undefined(inputs.mainAlphaSpec) {
|
|
145
|
+
comparison := numerator + " - vs - " + denominatorString
|
|
146
|
+
defaultConvMem := inputs.defaultConvMem
|
|
147
|
+
if defaultConvMem == undefined {
|
|
148
|
+
defaultConvMem = "16GiB"
|
|
149
|
+
}
|
|
150
|
+
defaultConvCpu := inputs.defaultConvCpu
|
|
151
|
+
if defaultConvCpu == undefined {
|
|
152
|
+
defaultConvCpu = 1
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// Process alpha chain
|
|
156
|
+
degImportParams := tcrdiscoDaPfconvParamsLib.getColumns(inputs.mainAlphaSpec, inputs.cdSubsetCol, numerator, comparison)
|
|
157
|
+
degPfAlpha := xsv.importFile(diffExec.getFile("robust_enrichment_alpha_" + numerator + ".csv"), "csv", degImportParams, {mem: defaultConvMem, cpu: defaultConvCpu})
|
|
158
|
+
|
|
159
|
+
// We just export robust enrichment for now, that will have a unique value per clonotype
|
|
160
|
+
robustEnrichmentPframeBuilderAlpha_clonotype.add(
|
|
161
|
+
numerator,
|
|
162
|
+
trace.inject(degPfAlpha["robustEnrichment.spec"]),
|
|
163
|
+
degPfAlpha["robustEnrichment.data"]
|
|
164
|
+
)
|
|
165
|
+
|
|
166
|
+
// Process beta chain if available
|
|
167
|
+
if !is_undefined(inputs.mainBetaSpec) {
|
|
168
|
+
degImportParamsBeta := tcrdiscoDaPfconvParamsLib.getColumns(inputs.mainBetaSpec, inputs.cdSubsetCol, numerator, comparison)
|
|
169
|
+
degPfBeta := xsv.importFile(diffExec.getFile("robust_enrichment_beta_" + numerator + ".csv"), "csv", degImportParamsBeta, {mem: defaultConvMem, cpu: defaultConvCpu})
|
|
170
|
+
|
|
171
|
+
/// We just export robust enrichment for now, that will have a unique value per clonotype
|
|
172
|
+
robustEnrichmentPframeBuilderBeta_clonotype.add(
|
|
173
|
+
numerator,
|
|
174
|
+
trace.inject(degPfBeta["robustEnrichment.spec"]),
|
|
175
|
+
degPfBeta["robustEnrichment.data"]
|
|
176
|
+
)
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
getEnrichedFrequenciesExec := exec.builder().
|
|
182
|
+
software(getEnrichedFrequenciesSoftware).
|
|
183
|
+
addFile("mainAlpha.tsv", mainAlphaTsv).
|
|
184
|
+
addFile("mainBeta.tsv", mainBetaTsv).
|
|
185
|
+
addFile("DA_alpha.csv", diffExec.getFile("DA_alpha.csv")).
|
|
186
|
+
addFile("DA_beta.csv", diffExec.getFile("DA_beta.csv")).
|
|
187
|
+
arg("--main_alpha").arg("mainAlpha.tsv").
|
|
188
|
+
arg("--main_beta").arg("mainBeta.tsv").
|
|
189
|
+
arg("--da_alpha").arg("DA_alpha.csv").
|
|
190
|
+
arg("--da_beta").arg("DA_beta.csv").
|
|
191
|
+
arg("-o").arg(".").
|
|
192
|
+
saveFile("main_alpha_frequencies.tsv").
|
|
193
|
+
saveFile("main_beta_frequencies.tsv").
|
|
194
|
+
saveFile("clonotype_to_subset_alpha.tsv").
|
|
195
|
+
saveFile("clonotype_to_subset_beta.tsv").
|
|
196
|
+
run()
|
|
197
|
+
mainAlphaFrequenciesTsv := getEnrichedFrequenciesExec.getFile("main_alpha_frequencies.tsv")
|
|
198
|
+
mainBetaFrequenciesTsv := getEnrichedFrequenciesExec.getFile("main_beta_frequencies.tsv")
|
|
199
|
+
clonotypeToSubsetAlpha := getEnrichedFrequenciesExec.getFile("clonotype_to_subset_alpha.tsv")
|
|
200
|
+
clonotypeToSubsetBeta := getEnrichedFrequenciesExec.getFile("clonotype_to_subset_beta.tsv")
|
|
201
|
+
|
|
202
|
+
// Build format 2 PFrames
|
|
203
|
+
robustEnrichmentPFAlpha_clonotype := undefined
|
|
204
|
+
robustEnrichmentPFBeta_clonotype := undefined
|
|
205
|
+
if !is_undefined(inputs.mainAlphaSpec) {
|
|
206
|
+
robustEnrichmentPFAlpha_clonotype = robustEnrichmentPframeBuilderAlpha_clonotype.build()
|
|
207
|
+
if !is_undefined(inputs.mainBetaSpec) {
|
|
208
|
+
robustEnrichmentPFBeta_clonotype = robustEnrichmentPframeBuilderBeta_clonotype.build()
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
return {
|
|
213
|
+
topTableFileAlpha: diffExec.getFile("topTable_alpha.csv"),
|
|
214
|
+
topTableFileBeta: diffExec.getFile("topTable_beta.csv"),
|
|
215
|
+
daFileAlpha: diffExec.getFile("DA_alpha.csv"),
|
|
216
|
+
daFileBeta: diffExec.getFile("DA_beta.csv"),
|
|
217
|
+
contrastMap: contrastMap,
|
|
218
|
+
mainAlphaFrequenciesTsv: mainAlphaFrequenciesTsv,
|
|
219
|
+
mainBetaFrequenciesTsv: mainBetaFrequenciesTsv,
|
|
220
|
+
clonotypeToSubsetAlpha: clonotypeToSubsetAlpha,
|
|
221
|
+
clonotypeToSubsetBeta: clonotypeToSubsetBeta,
|
|
222
|
+
robustEnrichmentPFAlpha_clonotype: robustEnrichmentPFAlpha_clonotype,
|
|
223
|
+
robustEnrichmentPFBeta_clonotype: robustEnrichmentPFBeta_clonotype
|
|
224
|
+
}
|
|
225
|
+
})
|
|
226
|
+
|
package/src/wf.test.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { tplTest } from "@platforma-sdk/test";
|
|
2
|
+
|
|
3
|
+
tplTest(
|
|
4
|
+
'should return a concatenated string',
|
|
5
|
+
async ({ helper, expect }) => {
|
|
6
|
+
const results = await helper.renderWorkflow("main", false, {
|
|
7
|
+
name: 'World'
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
const tengoMessage = results.output("tengoMessage", (a) => a?.getDataAsJson<string>());
|
|
11
|
+
expect(await tengoMessage.awaitStableValue()).eq('Hello from Tengo, World!');
|
|
12
|
+
}
|
|
13
|
+
);
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "es2022",
|
|
4
|
+
"module": "commonjs",
|
|
5
|
+
"moduleResolution": "node",
|
|
6
|
+
"esModuleInterop": true,
|
|
7
|
+
"strict": true,
|
|
8
|
+
"outDir": "./dist",
|
|
9
|
+
"rootDir": "./src",
|
|
10
|
+
"sourceMap": true,
|
|
11
|
+
"declaration": true
|
|
12
|
+
},
|
|
13
|
+
"types": [],
|
|
14
|
+
"include": ["src/**/*"],
|
|
15
|
+
"exclude": ["node_modules", "dist"]
|
|
16
|
+
}
|