@platforma-open/milaboratories.sequence-properties.workflow 1.1.2 → 1.2.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,6 +1,6 @@
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.0 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
package/CHANGELOG.md CHANGED
@@ -1,5 +1,18 @@
1
1
  # @platforma-open/MiLaboratories.sequence-properties.workflow
2
2
 
3
+ ## 1.2.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 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).
8
+
9
+ 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.
10
+
11
+ ### Patch Changes
12
+
13
+ - Updated dependencies [a3eaf4b]
14
+ - @platforma-open/milaboratories.sequence-properties.software@1.2.0
15
+
3
16
  ## 1.1.2
4
17
 
5
18
  ### Patch Changes
@@ -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,11 +1,11 @@
1
1
  {
2
2
  "name": "@platforma-open/milaboratories.sequence-properties.workflow",
3
- "version": "1.1.2",
3
+ "version": "1.2.0",
4
4
  "description": "Block Workflow",
5
5
  "type": "module",
6
6
  "dependencies": {
7
7
  "@platforma-sdk/workflow-tengo": "5.16.0",
8
- "@platforma-open/milaboratories.sequence-properties.software": "1.1.1"
8
+ "@platforma-open/milaboratories.sequence-properties.software": "1.2.0"
9
9
  },
10
10
  "devDependencies": {
11
11
  "@platforma-sdk/tengo-builder": "2.5.17",
@@ -47,6 +47,12 @@ vhh := func() {
47
47
  "disregard these thresholds for nanobody libraries."
48
48
  }
49
49
 
50
+ // R9 — Guruprasad instability index is undefined for sequences shorter than
51
+ // 10 residues; emitted in peptide mode whenever any peptide falls below the floor.
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
  })
@@ -14,6 +14,17 @@ messages := import(":messages")
14
14
 
15
15
  self.defineOutputs("propertiesPf", "exportPframe", "info")
16
16
 
17
+ // ΔCharge (pH 7.4 → 6.0) endpoints — fixed in v1 per spec; schema accepts
18
+ // additional pH pairs without breaking existing column identities.
19
+ CHARGE_SHIFT_PH_FROM := "7.4"
20
+ CHARGE_SHIFT_PH_TO := "6.0"
21
+
22
+ // Spec R6b — same description on every chargeShift column (peptide / CDR3 / Fv).
23
+ // Trimmed to ~30 words for the column-header tooltip; PlAgDataTableV2 clips the
24
+ // top edge against the page header. Magnitude rule and scope-exclusion caveats
25
+ // live in pcolumn-spec.md / the spec, not in the tooltip.
26
+ 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)."
27
+
17
28
  // Receptor + chain → human label fragments (CDR3 / full-chain).
18
29
  // Spec R13a: PColumn name and chain domain are unchanged; only the label varies.
19
30
  labelFragments := func(receptor, chain) {
@@ -81,6 +92,13 @@ self.body(func(args) {
81
92
  }
82
93
  }
83
94
 
95
+ // R9 — Instability Index is NA for peptides shorter than 10 aa. Surface a
96
+ // banner in peptide mode whenever any row falls below the floor so the
97
+ // user understands why the Instability Index column is blank.
98
+ if mode == "peptide" && stats.hasPeptideBelowInstabilityFloor == true {
99
+ infoMessages += [messages.peptidesShortInstability()]
100
+ }
101
+
84
102
  infoBlob := smart.createValueResource(constants.RTYPE_JSON, canonical.encode({
85
103
  mode: mode,
86
104
  receptor: receptor,
@@ -106,6 +124,18 @@ self.body(func(args) {
106
124
  "pl7.app/table/orderPriority": "70000"
107
125
  })]
108
126
 
127
+ columns += [makeCol("chargeShift_peptide", "pl7.app/chargeShift", "Double",
128
+ "Peptide ΔCharge (pH 7.4 → 6.0)", {
129
+ "pl7.app/feature": "peptide",
130
+ "pl7.app/pH/from": CHARGE_SHIFT_PH_FROM,
131
+ "pl7.app/pH/to": CHARGE_SHIFT_PH_TO
132
+ }, {
133
+ "pl7.app/format": ".2f",
134
+ "pl7.app/description": CHARGE_SHIFT_DESC,
135
+ "pl7.app/table/visibility": "default",
136
+ "pl7.app/table/orderPriority": "69950"
137
+ })]
138
+
109
139
  columns += [makeCol("gravy_peptide", "pl7.app/hydrophobicity", "Double",
110
140
  "Hydrophobicity (GRAVY)", dom, {
111
141
  "pl7.app/format": ".3f",
@@ -206,6 +236,18 @@ self.body(func(args) {
206
236
  "pl7.app/table/visibility": "default",
207
237
  "pl7.app/table/orderPriority": string(chargeOrder)
208
238
  })]
239
+ columns += [makeCol("chargeShift_" + chain + "_CDR3", "pl7.app/chargeShift", "Double",
240
+ frag.cdr3 + " ΔCharge (pH 7.4 → 6.0)", {
241
+ "pl7.app/feature": "CDR3",
242
+ "pl7.app/vdj/scClonotypeChain": chain,
243
+ "pl7.app/pH/from": CHARGE_SHIFT_PH_FROM,
244
+ "pl7.app/pH/to": CHARGE_SHIFT_PH_TO
245
+ }, {
246
+ "pl7.app/format": ".2f",
247
+ "pl7.app/description": CHARGE_SHIFT_DESC,
248
+ "pl7.app/table/visibility": "default",
249
+ "pl7.app/table/orderPriority": string(chargeOrder - 50)
250
+ })]
209
251
  columns += [makeCol("gravy_" + chain + "_CDR3", "pl7.app/hydrophobicity", "Double",
210
252
  frag.cdr3 + " Hydrophobicity (GRAVY)", cdr3Dom, {
211
253
  "pl7.app/format": ".3f",
@@ -308,6 +350,17 @@ self.body(func(args) {
308
350
  "pl7.app/table/visibility": "default",
309
351
  "pl7.app/table/orderPriority": "65100"
310
352
  })]
353
+ columns += [makeCol("chargeShift_Fv", "pl7.app/chargeShift", "Double",
354
+ "Fv ΔCharge (pH 7.4 → 6.0)", {
355
+ "pl7.app/feature": "Fv",
356
+ "pl7.app/pH/from": CHARGE_SHIFT_PH_FROM,
357
+ "pl7.app/pH/to": CHARGE_SHIFT_PH_TO
358
+ }, {
359
+ "pl7.app/format": ".2f",
360
+ "pl7.app/description": CHARGE_SHIFT_DESC,
361
+ "pl7.app/table/visibility": "default",
362
+ "pl7.app/table/orderPriority": "65050"
363
+ })]
311
364
  columns += [makeCol("pi_Fv", "pl7.app/isoelectricPoint", "Double",
312
365
  "Fv Isoelectric Point (pI)", fvDom, {
313
366
  "pl7.app/format": ".2f",