@platforma-open/milaboratories.sequence-properties.workflow 1.1.2 → 1.2.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,15 +1,17 @@
1
1
   WARN  Issue while reading "/home/runner/work/sequence-properties/sequence-properties/.npmrc". Failed to replace env in config: ${NPMJS_TOKEN}
2
2
 
3
- > @platforma-open/milaboratories.sequence-properties.workflow@1.1.2 build /home/runner/work/sequence-properties/sequence-properties/workflow
3
+ > @platforma-open/milaboratories.sequence-properties.workflow@1.2.1 build /home/runner/work/sequence-properties/sequence-properties/workflow
4
4
  > shx rm -rf dist && pl-tengo check && pl-tengo build
5
5
 
6
6
  info: Skipping unknown file type: wf.test.ts
7
+ Processing "src/columns.lib.tengo"...
7
8
  Processing "src/main.tpl.tengo"...
8
9
  Processing "src/messages.lib.tengo"...
9
10
  Processing "src/process.tpl.tengo"...
10
11
  No syntax errors found.
11
12
  info: Skipping unknown file type: wf.test.ts
12
13
  info: Compiling 'dist'...
14
+ info: - writing /home/runner/work/sequence-properties/sequence-properties/workflow/dist/tengo/lib/columns.lib.tengo
13
15
  info: - writing /home/runner/work/sequence-properties/sequence-properties/workflow/dist/tengo/lib/messages.lib.tengo
14
16
  info: - writing /home/runner/work/sequence-properties/sequence-properties/workflow/dist/tengo/tpl/process.plj.gz
15
17
  info: - writing /home/runner/work/sequence-properties/sequence-properties/workflow/dist/tengo/tpl/main.plj.gz
package/CHANGELOG.md CHANGED
@@ -1,5 +1,24 @@
1
1
  # @platforma-open/MiLaboratories.sequence-properties.workflow
2
2
 
3
+ ## 1.2.1
4
+
5
+ ### Patch Changes
6
+
7
+ - 73b4e4d: Enable linker usage to show plot options
8
+
9
+ ## 1.2.0
10
+
11
+ ### Minor Changes
12
+
13
+ - a3eaf4b: Add ΔCharge (pH 7.4 → 6.0) metric — `pl7.app/chargeShift` — emitted at peptide, CDR3 (per chain), and Fv scopes. Captures pH-switching capacity (FcRn recycling, endosomal release); negative values mean the molecule gains positive charge on acidification, the productive direction for histidine-driven pH switching. Histidine dominates the metric (~−0.46 per His; pKa ~6.0 sits in the window). Domain carries the pH endpoints (`pl7.app/pH/from`, `pl7.app/pH/to`) so additional pH pairs can land later without breaking the v1 column identity. Default-visible alongside the static charge column at each scope; not marked `isScore` (interpretive, not a Lead Selection ranking criterion).
14
+
15
+ Performance: cache per-sequence `_prepare`, `ProteinAnalysis`, and `IsoelectricPoint` via a `SequenceContext` so each sequence does the BioPython setup work once instead of per-property. Pipeline reuses the full-chain context for the Fv pass (one `IsoelectricPoint(IPC2_PROTEIN, include_cys=False)` shared between `charge_at_pH(7.0)` and pI bisection per chain). DataFrames are built columnarly (dict-of-lists) instead of via list-of-dicts. Output is byte-identical to pre-refactor on the corpus tests; ~1.7× faster on per-property micro-bench, end-to-end ~40k peptides/s and ~10k antibody-clones/s with full-chain + Fv. CDR3 chain-mode byte-stability tests added.
16
+
17
+ ### Patch Changes
18
+
19
+ - Updated dependencies [a3eaf4b]
20
+ - @platforma-open/milaboratories.sequence-properties.software@1.2.0
21
+
3
22
  ## 1.1.2
4
23
 
5
24
  ### Patch Changes
@@ -0,0 +1,446 @@
1
+
2
+
3
+
4
+
5
+
6
+
7
+
8
+
9
+
10
+
11
+
12
+
13
+
14
+
15
+
16
+ ll := import("@platforma-sdk/workflow-tengo:ll")
17
+
18
+
19
+
20
+ CHARGE_SHIFT_PH_FROM := "7.4"
21
+ CHARGE_SHIFT_PH_TO := "6.0"
22
+
23
+
24
+
25
+
26
+
27
+ CHARGE_SHIFT_DESC := "Net charge change from pH 7.4 (blood) to pH 6.0 (endosome). Negative values mean the molecule gains positive charge on acidification — the productive direction for histidine-driven pH switching. Histidine dominates (~−0.46 per His)."
28
+
29
+
30
+
31
+ labelFragments := func(receptor, chain) {
32
+ if receptor == "TCRAB" {
33
+ if chain == "A" { return { cdr3: "CDR-α3", fullChain: "Vα" } }
34
+ if chain == "B" { return { cdr3: "CDR-β3", fullChain: "Vβ" } }
35
+ }
36
+ if receptor == "TCRGD" {
37
+ if chain == "A" { return { cdr3: "CDR-γ3", fullChain: "Vγ" } }
38
+ if chain == "B" { return { cdr3: "CDR-δ3", fullChain: "Vδ" } }
39
+ }
40
+
41
+ if chain == "A" { return { cdr3: "CDR-H3", fullChain: "VH" } }
42
+ return { cdr3: "CDR-L3", fullChain: "VL" }
43
+ }
44
+
45
+
46
+
47
+
48
+
49
+ makeCol := func(tsvCol, valName, valueType, label, domain, annotations) {
50
+ newAnnotations := {}
51
+ if annotations {
52
+ for k, v in annotations {
53
+ newAnnotations[k] = v
54
+ }
55
+ }
56
+ newAnnotations["pl7.app/label"] = label
57
+ spec := {
58
+ name: valName,
59
+ valueType: valueType,
60
+ domain: domain,
61
+ annotations: newAnnotations
62
+ }
63
+ return { column: tsvCol, id: tsvCol, naRegex: "", allowNA: true, spec: spec }
64
+ }
65
+
66
+
67
+
68
+
69
+
70
+
71
+ buildPeptideColumns := func() {
72
+ dom := { "pl7.app/feature": "peptide" }
73
+ cols := []
74
+
75
+ cols += [makeCol("charge_peptide", "pl7.app/charge", "Double",
76
+ "Net Charge (pH 7)", dom, {
77
+ "pl7.app/format": ".2f",
78
+ "pl7.app/isScore": "true",
79
+ "pl7.app/description": "Net charge at pH 7 (Henderson-Hasselbalch, IPC 2.0 peptide pKa set). Positive = net basic (Arg, Lys, His dominate); negative = net acidic (Asp, Glu dominate). No universal preferred direction.",
80
+ "pl7.app/table/visibility": "default",
81
+ "pl7.app/table/orderPriority": "70000"
82
+ })]
83
+
84
+ cols += [makeCol("chargeShift_peptide", "pl7.app/chargeShift", "Double",
85
+ "Peptide ΔCharge (pH 7.4 → 6.0)", {
86
+ "pl7.app/feature": "peptide",
87
+ "pl7.app/pH/from": CHARGE_SHIFT_PH_FROM,
88
+ "pl7.app/pH/to": CHARGE_SHIFT_PH_TO
89
+ }, {
90
+ "pl7.app/format": ".2f",
91
+ "pl7.app/description": CHARGE_SHIFT_DESC,
92
+ "pl7.app/table/visibility": "default",
93
+ "pl7.app/table/orderPriority": "69950"
94
+ })]
95
+
96
+ cols += [makeCol("gravy_peptide", "pl7.app/hydrophobicity", "Double",
97
+ "Hydrophobicity (GRAVY)", dom, {
98
+ "pl7.app/format": ".3f",
99
+ "pl7.app/isScore": "true",
100
+ "pl7.app/score/rankingOrder": "increasing",
101
+ "pl7.app/description": "rankingOrder: increasing reflects preference for lower hydrophobicity. Invert direction in Lead Selection for hydrophobic-target applications.",
102
+ "pl7.app/table/visibility": "default",
103
+ "pl7.app/table/orderPriority": "69900"
104
+ })]
105
+
106
+ cols += [makeCol("mw_peptide", "pl7.app/molecularWeight", "Double",
107
+ "Molecular Weight (Da, average masses)", dom, {
108
+ "pl7.app/format": ".1f",
109
+ "pl7.app/min": "0",
110
+ "pl7.app/table/visibility": "default",
111
+ "pl7.app/table/orderPriority": "69800"
112
+ })]
113
+
114
+ cols += [makeCol("pi_peptide", "pl7.app/isoelectricPoint", "Double",
115
+ "Isoelectric Point (pI)", dom, {
116
+ "pl7.app/format": ".2f",
117
+ "pl7.app/min": "0",
118
+ "pl7.app/max": "14",
119
+ "pl7.app/table/visibility": "default",
120
+ "pl7.app/table/orderPriority": "69700"
121
+ })]
122
+
123
+ cols += [makeCol("eox_peptide", "pl7.app/extinctionCoefficientOx", "Double",
124
+ "Extinction Coeff., Oxidized (M⁻¹cm⁻¹)", dom, {
125
+ "pl7.app/format": ".0f",
126
+ "pl7.app/min": "0",
127
+ "pl7.app/description": "Assumes all Cys are in disulfide bonds. For unprotected linear peptides use the reduced form.",
128
+ "pl7.app/table/visibility": "optional",
129
+ "pl7.app/table/orderPriority": "69600"
130
+ })]
131
+
132
+ cols += [makeCol("ered_peptide", "pl7.app/extinctionCoefficientRed", "Double",
133
+ "Extinction Coeff., Reduced (M⁻¹cm⁻¹)", dom, {
134
+ "pl7.app/format": ".0f",
135
+ "pl7.app/min": "0",
136
+ "pl7.app/description": "Extinction coefficient at 280 nm, disulfide bonds reduced (Cys contribution omitted). A value of 0 means no Tyr or Trp — A280-based quantification is not possible.",
137
+ "pl7.app/table/visibility": "optional",
138
+ "pl7.app/table/orderPriority": "69500"
139
+ })]
140
+
141
+ cols += [makeCol("instability_peptide", "pl7.app/instabilityIndex", "Double",
142
+ "Instability Index", dom, {
143
+ "pl7.app/format": ".2f",
144
+ "pl7.app/description": "Guruprasad index — derived from globular proteins. The II > 40 threshold does not apply to short linear peptides; use as a relative composition ranking aid only.",
145
+ "pl7.app/table/visibility": "default",
146
+ "pl7.app/table/orderPriority": "69400"
147
+ })]
148
+
149
+ cols += [makeCol("aliphatic_peptide", "pl7.app/aliphaticIndex", "Double",
150
+ "Aliphatic Index", dom, {
151
+ "pl7.app/format": ".1f",
152
+ "pl7.app/min": "0",
153
+ "pl7.app/description": "Measures fraction of nonpolar aliphatic residues (Ala, Val, Ile, Leu). For short linear peptides, thermostability interpretation does not apply — the Ikai index was derived for globular mesophilic enzymes, and thermostability is not a meaningful concept for unstructured peptides. Useful as a composition indicator and a proxy for hydrophobic character alongside GRAVY — both metrics increase with Ala/Val/Ile/Leu content, but neither has a universal preferred direction for therapeutic peptides.",
154
+ "pl7.app/table/visibility": "optional",
155
+ "pl7.app/table/orderPriority": "69300"
156
+ })]
157
+
158
+ cols += [makeCol("aromaticity_peptide", "pl7.app/aromaticity", "Double",
159
+ "Aromaticity", dom, {
160
+ "pl7.app/format": ".3f",
161
+ "pl7.app/min": "0",
162
+ "pl7.app/max": "1",
163
+ "pl7.app/description": "Fraction of aromatic residues (Phe, Trp, Tyr).",
164
+ "pl7.app/table/visibility": "optional",
165
+ "pl7.app/table/orderPriority": "69200"
166
+ })]
167
+
168
+ return cols
169
+ }
170
+
171
+
172
+
173
+ CDR3_CHARGE_DESC := {
174
+ A: "Strongly positive CDR3 charge correlates with polyreactivity via electrostatic interactions. No universal preferred direction in Lead Selection. IPC 2.0 peptide pKa set.",
175
+ B: "Strongly positive CDR-L3 charge contributes to paratope polyreactivity. Strongly negative charge is primarily a PK concern. No universal preferred direction. IPC 2.0 peptide pKa set."
176
+ }
177
+ CDR3_GRAVY_DESC := {
178
+ A: "Lower hydrophobicity preferred for developability. CDR3 GRAVY > 0 is an informal aggregation/polyreactivity heuristic.",
179
+ B: "Same aggregation and polyreactivity signal as CDR-H3 hydrophobicity; lower independent predictive weight. The TAP score uses combined 6-CDR GRAVY — CDR-L3 alone has limited independent validation."
180
+ }
181
+
182
+ buildCdr3Columns := func(receptor, chains) {
183
+ cols := []
184
+ cdr3OrderA := 68000
185
+ cdr3OrderB := 67700
186
+ for chain in chains {
187
+ frag := labelFragments(receptor, chain)
188
+ cdr3Dom := { "pl7.app/feature": "CDR3", "pl7.app/vdj/scClonotypeChain": chain }
189
+ chargeOrder := (chain == "A" ? cdr3OrderA : cdr3OrderB)
190
+ gravyOrder := chargeOrder - 100
191
+
192
+ cols += [makeCol("charge_" + chain + "_CDR3", "pl7.app/charge", "Double",
193
+ frag.cdr3 + " Net Charge (pH 7)", cdr3Dom, {
194
+ "pl7.app/format": ".2f",
195
+ "pl7.app/isScore": "true",
196
+ "pl7.app/description": CDR3_CHARGE_DESC[chain],
197
+ "pl7.app/table/visibility": "default",
198
+ "pl7.app/table/orderPriority": string(chargeOrder)
199
+ })]
200
+ cols += [makeCol("chargeShift_" + chain + "_CDR3", "pl7.app/chargeShift", "Double",
201
+ frag.cdr3 + " ΔCharge (pH 7.4 → 6.0)", {
202
+ "pl7.app/feature": "CDR3",
203
+ "pl7.app/vdj/scClonotypeChain": chain,
204
+ "pl7.app/pH/from": CHARGE_SHIFT_PH_FROM,
205
+ "pl7.app/pH/to": CHARGE_SHIFT_PH_TO
206
+ }, {
207
+ "pl7.app/format": ".2f",
208
+ "pl7.app/description": CHARGE_SHIFT_DESC,
209
+ "pl7.app/table/visibility": "default",
210
+ "pl7.app/table/orderPriority": string(chargeOrder - 50)
211
+ })]
212
+ cols += [makeCol("gravy_" + chain + "_CDR3", "pl7.app/hydrophobicity", "Double",
213
+ frag.cdr3 + " Hydrophobicity (GRAVY)", cdr3Dom, {
214
+ "pl7.app/format": ".3f",
215
+ "pl7.app/isScore": "true",
216
+ "pl7.app/score/rankingOrder": "increasing",
217
+ "pl7.app/description": CDR3_GRAVY_DESC[chain],
218
+ "pl7.app/table/visibility": "default",
219
+ "pl7.app/table/orderPriority": string(gravyOrder)
220
+ })]
221
+ }
222
+ return cols
223
+ }
224
+
225
+ buildFullChainColumns := func(receptor, fullChains) {
226
+ cols := []
227
+ fcOrderBaseA := 67000
228
+ fcOrderBaseB := 66000
229
+ for chain in fullChains {
230
+ frag := labelFragments(receptor, chain)
231
+ fcDom := { "pl7.app/feature": "VDJRegion", "pl7.app/vdj/scClonotypeChain": chain }
232
+ base := (chain == "A" ? fcOrderBaseA : fcOrderBaseB)
233
+ fcLabel := frag.fullChain
234
+
235
+ cols += [makeCol("charge_" + chain + "_VDJRegion", "pl7.app/charge", "Double",
236
+ fcLabel + " Net Charge (pH 7)", fcDom, {
237
+ "pl7.app/format": ".2f",
238
+ "pl7.app/isScore": "true",
239
+ "pl7.app/description": "Non-monotonic vs developability: strongly positive correlates with polyreactivity; strongly negative with rapid clearance.",
240
+ "pl7.app/table/visibility": "default",
241
+ "pl7.app/table/orderPriority": string(base)
242
+ })]
243
+ cols += [makeCol("pi_" + chain + "_VDJRegion", "pl7.app/isoelectricPoint", "Double",
244
+ fcLabel + " Isoelectric Point (pI)", fcDom, {
245
+ "pl7.app/format": ".2f",
246
+ "pl7.app/isScore": "true",
247
+ "pl7.app/min": "0",
248
+ "pl7.app/max": "14",
249
+ "pl7.app/table/visibility": "default",
250
+ "pl7.app/table/orderPriority": string(base - 100)
251
+ })]
252
+ cols += [makeCol("gravy_" + chain + "_VDJRegion", "pl7.app/hydrophobicity", "Double",
253
+ fcLabel + " Hydrophobicity (GRAVY)", fcDom, {
254
+ "pl7.app/format": ".3f",
255
+ "pl7.app/description": "Framework regions dominate; weak developability signal at chain level — CDR3 hydrophobicity is more discriminating.",
256
+ "pl7.app/table/visibility": "default",
257
+ "pl7.app/table/orderPriority": string(base - 200)
258
+ })]
259
+ cols += [makeCol("mw_" + chain + "_VDJRegion", "pl7.app/molecularWeight", "Double",
260
+ fcLabel + " Molecular Weight (Da, average masses)", fcDom, {
261
+ "pl7.app/format": ".1f",
262
+ "pl7.app/min": "0",
263
+ "pl7.app/description": "Unglycosylated sequence mass — does not include N-glycan contributions from any NXS/NXT sequons in the variable region.",
264
+ "pl7.app/table/visibility": "optional",
265
+ "pl7.app/table/orderPriority": string(base - 300)
266
+ })]
267
+ cols += [makeCol("eox_" + chain + "_VDJRegion", "pl7.app/extinctionCoefficientOx", "Double",
268
+ fcLabel + " Extinction Coeff., Oxidized (M⁻¹cm⁻¹)", fcDom, {
269
+ "pl7.app/format": ".0f",
270
+ "pl7.app/min": "0",
271
+ "pl7.app/table/visibility": "optional",
272
+ "pl7.app/table/orderPriority": string(base - 400)
273
+ })]
274
+ cols += [makeCol("ered_" + chain + "_VDJRegion", "pl7.app/extinctionCoefficientRed", "Double",
275
+ fcLabel + " Extinction Coeff., Reduced (M⁻¹cm⁻¹)", fcDom, {
276
+ "pl7.app/format": ".0f",
277
+ "pl7.app/min": "0",
278
+ "pl7.app/table/visibility": "optional",
279
+ "pl7.app/table/orderPriority": string(base - 500)
280
+ })]
281
+ cols += [makeCol("instability_" + chain + "_VDJRegion", "pl7.app/instabilityIndex", "Double",
282
+ fcLabel + " Instability Index", fcDom, {
283
+ "pl7.app/format": ".2f",
284
+ "pl7.app/description": "Guruprasad index, calibrated for in-vitro stability of soluble globular proteins via dipeptide composition. Weak predictor of antibody Tm — use as supplementary ranking aid.",
285
+ "pl7.app/table/visibility": "optional",
286
+ "pl7.app/table/orderPriority": string(base - 600)
287
+ })]
288
+ cols += [makeCol("aliphatic_" + chain + "_VDJRegion", "pl7.app/aliphaticIndex", "Double",
289
+ fcLabel + " Aliphatic Index", fcDom, {
290
+ "pl7.app/format": ".1f",
291
+ "pl7.app/min": "0",
292
+ "pl7.app/description": "Ikai aliphatic index, derived from globular mesophilic enzymes. Weak correlation with antibody Tm. No rankingOrder — high values can correlate with aggregation propensity.",
293
+ "pl7.app/table/visibility": "optional",
294
+ "pl7.app/table/orderPriority": string(base - 700)
295
+ })]
296
+ cols += [makeCol("aromaticity_" + chain + "_VDJRegion", "pl7.app/aromaticity", "Double",
297
+ fcLabel + " Aromaticity", fcDom, {
298
+ "pl7.app/format": ".3f",
299
+ "pl7.app/min": "0",
300
+ "pl7.app/max": "1",
301
+ "pl7.app/description": "Fraction of aromatic residues (Phe, Trp, Tyr) over the full chain. Framework dominates; CDR-specific aromaticity is a stronger predictor (Phase 2).",
302
+ "pl7.app/table/visibility": "optional",
303
+ "pl7.app/table/orderPriority": string(base - 800)
304
+ })]
305
+ }
306
+ return cols
307
+ }
308
+
309
+ buildFvColumns := func() {
310
+ cols := []
311
+ fvDom := { "pl7.app/feature": "Fv" }
312
+
313
+ cols += [makeCol("charge_Fv", "pl7.app/charge", "Double",
314
+ "Fv Net Charge (pH 7)", fvDom, {
315
+ "pl7.app/format": ".2f",
316
+ "pl7.app/isScore": "true",
317
+ "pl7.app/table/visibility": "default",
318
+ "pl7.app/table/orderPriority": "65100"
319
+ })]
320
+ cols += [makeCol("chargeShift_Fv", "pl7.app/chargeShift", "Double",
321
+ "Fv ΔCharge (pH 7.4 → 6.0)", {
322
+ "pl7.app/feature": "Fv",
323
+ "pl7.app/pH/from": CHARGE_SHIFT_PH_FROM,
324
+ "pl7.app/pH/to": CHARGE_SHIFT_PH_TO
325
+ }, {
326
+ "pl7.app/format": ".2f",
327
+ "pl7.app/description": CHARGE_SHIFT_DESC,
328
+ "pl7.app/table/visibility": "default",
329
+ "pl7.app/table/orderPriority": "65050"
330
+ })]
331
+ cols += [makeCol("pi_Fv", "pl7.app/isoelectricPoint", "Double",
332
+ "Fv Isoelectric Point (pI)", fvDom, {
333
+ "pl7.app/format": ".2f",
334
+ "pl7.app/isScore": "true",
335
+ "pl7.app/min": "0",
336
+ "pl7.app/max": "14",
337
+ "pl7.app/description": "Variable region (VH+VL) only. Fv pI is typically 2–4 pH units higher than whole-IgG cIEF measurements, which include constant regions (IgG1 Fc pI ≈ 5–6).",
338
+ "pl7.app/table/visibility": "default",
339
+ "pl7.app/table/orderPriority": "65000"
340
+ })]
341
+ cols += [makeCol("eox_Fv", "pl7.app/extinctionCoefficientOx", "Double",
342
+ "Fv Extinction Coeff., Oxidized (M⁻¹cm⁻¹)", fvDom, {
343
+ "pl7.app/format": ".0f",
344
+ "pl7.app/min": "0",
345
+ "pl7.app/description": "Variable region (VH+VL) only — does not include constant regions. For whole-IgG A280 quantification, use the full-antibody ε.",
346
+ "pl7.app/table/visibility": "optional",
347
+ "pl7.app/table/orderPriority": "64900"
348
+ })]
349
+ cols += [makeCol("ered_Fv", "pl7.app/extinctionCoefficientRed", "Double",
350
+ "Fv Extinction Coeff., Reduced (M⁻¹cm⁻¹)", fvDom, {
351
+ "pl7.app/format": ".0f",
352
+ "pl7.app/min": "0",
353
+ "pl7.app/description": "Variable region (VH+VL) only, disulfide bonds reduced (Cys contribution omitted). A value of 0 means no Tyr or Trp — A280-based quantification is not possible.",
354
+ "pl7.app/table/visibility": "optional",
355
+ "pl7.app/table/orderPriority": "64800"
356
+ })]
357
+ cols += [makeCol("mw_Fv", "pl7.app/molecularWeight", "Double",
358
+ "Fv Molecular Weight (Da, average masses)", fvDom, {
359
+ "pl7.app/format": ".1f",
360
+ "pl7.app/min": "0",
361
+ "pl7.app/description": "Unglycosylated sequence mass (VH + VL).",
362
+ "pl7.app/table/visibility": "optional",
363
+ "pl7.app/table/orderPriority": "64700"
364
+ })]
365
+ return cols
366
+ }
367
+
368
+ buildColumns := func(args) {
369
+ if args.mode == "peptide" {
370
+ return buildPeptideColumns()
371
+ }
372
+ cols := buildCdr3Columns(args.receptor, args.chains)
373
+ cols += buildFullChainColumns(args.receptor, args.fullChains)
374
+ if args.hasFv {
375
+ cols += buildFvColumns()
376
+ }
377
+ return cols
378
+ }
379
+
380
+
381
+
382
+
383
+
384
+
385
+
386
+ cloneSpec := func(spec, domainExtras, annotationExtras) {
387
+ newDomain := {}
388
+ if spec.domain {
389
+ for k, v in spec.domain { newDomain[k] = v }
390
+ }
391
+ if domainExtras {
392
+ for k, v in domainExtras { newDomain[k] = v }
393
+ }
394
+ newAnnotations := {}
395
+ if spec.annotations {
396
+ for k, v in spec.annotations { newAnnotations[k] = v }
397
+ }
398
+ if annotationExtras {
399
+ for k, v in annotationExtras { newAnnotations[k] = v }
400
+ }
401
+ return {
402
+ name: spec.name,
403
+ valueType: spec.valueType,
404
+ domain: newDomain,
405
+ annotations: newAnnotations
406
+ }
407
+ }
408
+
409
+ wrap := func(col, newSpec) {
410
+ return {
411
+ column: col.column,
412
+ id: col.id,
413
+ naRegex: col.naRegex,
414
+ allowNA: col.allowNA,
415
+ spec: newSpec
416
+ }
417
+ }
418
+
419
+
420
+
421
+
422
+
423
+ forPropertiesPf := func(args) {
424
+ cols := buildColumns(args)
425
+ out := []
426
+ for col in cols {
427
+ out += [wrap(col, cloneSpec(col.spec, undefined, { "pl7.app/isOutput": "true" }))]
428
+ }
429
+ return out
430
+ }
431
+
432
+ forExport := func(args, blockId) {
433
+ cols := buildColumns(args)
434
+ out := []
435
+ for col in cols {
436
+ if !col.spec.annotations { continue }
437
+ if col.spec.annotations["pl7.app/isScore"] != "true" { continue }
438
+ out += [wrap(col, cloneSpec(col.spec, { "pl7.app/blockId": blockId }, undefined))]
439
+ }
440
+ return out
441
+ }
442
+
443
+ export ll.toStrict({
444
+ forPropertiesPf: forPropertiesPf,
445
+ forExport: forExport
446
+ })
@@ -47,6 +47,12 @@ vhh := func() {
47
47
  "disregard these thresholds for nanobody libraries."
48
48
  }
49
49
 
50
+
51
+
52
+ peptidesShortInstability := func() {
53
+ return "Instability Index applies only to peptides ≥10 aa; shorter peptides show blank values."
54
+ }
55
+
50
56
  export ll.toStrict({
51
57
  partialChainMissingFullChain: partialChainMissingFullChain,
52
58
  partialChainNoCdr3: partialChainNoCdr3,
@@ -54,5 +60,6 @@ export ll.toStrict({
54
60
  cdr3OnlyInput: cdr3OnlyInput,
55
61
  gammaDeltaTcr: gammaDeltaTcr,
56
62
  receptorNotDetected: receptorNotDetected,
57
- vhh: vhh
63
+ vhh: vhh,
64
+ peptidesShortInstability: peptidesShortInstability
58
65
  })
Binary file
Binary file
package/package.json CHANGED
@@ -1,15 +1,15 @@
1
1
  {
2
2
  "name": "@platforma-open/milaboratories.sequence-properties.workflow",
3
- "version": "1.1.2",
3
+ "version": "1.2.1",
4
4
  "description": "Block Workflow",
5
5
  "type": "module",
6
6
  "dependencies": {
7
- "@platforma-sdk/workflow-tengo": "5.16.0",
8
- "@platforma-open/milaboratories.sequence-properties.software": "1.1.1"
7
+ "@platforma-sdk/workflow-tengo": "5.21.0",
8
+ "@platforma-open/milaboratories.sequence-properties.software": "1.2.0"
9
9
  },
10
10
  "devDependencies": {
11
- "@platforma-sdk/tengo-builder": "2.5.17",
12
- "@platforma-sdk/test": "1.69.0"
11
+ "@platforma-sdk/tengo-builder": "2.5.26",
12
+ "@platforma-sdk/test": "1.75.6"
13
13
  },
14
14
  "peerDependencies": {
15
15
  "vitest": "*"