@platforma-open/milaboratories.top-antibodies 4.3.0 → 4.3.2
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/block-pack/main.plj.gz +0 -0
- package/block-pack/manifest.json +1 -1
- package/block-pack/model.json +1 -1
- package/block-pack/published.json +1 -1
- package/block-pack/ui.tgz +0 -0
- package/dist/AGENTS.d.ts +34 -19
- package/dist/AGENTS.d.ts.map +1 -1
- package/dist/index.d.ts +34 -19
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +89 -38
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -13996,13 +13996,57 @@ function computeDefaultFilters(scores, anchorRef) {
|
|
|
13996
13996
|
}
|
|
13997
13997
|
return defaultFilters;
|
|
13998
13998
|
}
|
|
13999
|
+
/**
|
|
14000
|
+
* Which pipeline produced the anchor's records, from the run-id key on its record axis:
|
|
14001
|
+
*
|
|
14002
|
+
* pl7.app/peptide/extractionRunId peptide-extraction
|
|
14003
|
+
* pl7.app/repertoire/extractionRunId synthetic-repertoire-profiler
|
|
14004
|
+
* pl7.app/vdj/clonotypingRunId MiXCR, and import-vdj-data's imported sets
|
|
14005
|
+
*
|
|
14006
|
+
* Reads the domain, not the axis name: clonotypeKey and scClonotypeKey are migrating to
|
|
14007
|
+
* pl7.app/variantKey, after which the name discriminates nothing. The axis-name checks below are
|
|
14008
|
+
* a fallback for producers that have not migrated yet.
|
|
14009
|
+
*
|
|
14010
|
+
* Does not say how a receptor dataset arrived. Uploaded sequences and MiXCR output are both
|
|
14011
|
+
* `vdj`. Whether specific columns exist is a separate question — see {@link hasGeneCalls}.
|
|
14012
|
+
*/
|
|
14013
|
+
function recordSource(anchorSpec) {
|
|
14014
|
+
const keyAxis = anchorSpec.axesSpec[1];
|
|
14015
|
+
if (keyAxis === void 0) return "unknown";
|
|
14016
|
+
const domain = keyAxis.domain ?? {};
|
|
14017
|
+
if (domain["pl7.app/peptide/extractionRunId"] !== void 0) return "peptide";
|
|
14018
|
+
if (domain["pl7.app/repertoire/extractionRunId"] !== void 0) return "amplicon";
|
|
14019
|
+
if (domain["pl7.app/vdj/clonotypingRunId"] !== void 0) return "vdj";
|
|
14020
|
+
if (keyAxis.name === "pl7.app/vdj/clonotypeKey" || keyAxis.name === "pl7.app/vdj/scClonotypeKey") return "vdj";
|
|
14021
|
+
return "unknown";
|
|
14022
|
+
}
|
|
14023
|
+
/** True for the two producers whose records are peptides or synthetic variants, not receptors. */
|
|
14024
|
+
function isPeptideOrAmplicon(anchorSpec) {
|
|
14025
|
+
const source = recordSource(anchorSpec);
|
|
14026
|
+
return source === "peptide" || source === "amplicon";
|
|
14027
|
+
}
|
|
14028
|
+
/**
|
|
14029
|
+
* Whether the dataset carries V/J gene calls — needed by CDR3 V Spectratype, V/J Gene Usage and
|
|
14030
|
+
* Kabat renumbering.
|
|
14031
|
+
*
|
|
14032
|
+
* Separate from {@link recordSource} on purpose: an uploaded set and a MiXCR set are both `vdj`,
|
|
14033
|
+
* but only MiXCR's has gene calls.
|
|
14034
|
+
*
|
|
14035
|
+
* TEMPORARY. This infers from the axis, and no variantKey producer emits gene calls today. When
|
|
14036
|
+
* MiXCR migrates to that axis this returns false for MiXCR too and both sections silently
|
|
14037
|
+
* disappear. Nothing structural separates the cases then — same axis name, same
|
|
14038
|
+
* clonotypingRunId — so replace it with a result-pool query for the gene columns.
|
|
14039
|
+
*/
|
|
14040
|
+
function hasGeneCalls(anchorSpec) {
|
|
14041
|
+
return anchorSpec.axesSpec[1]?.name !== "pl7.app/variantKey";
|
|
14042
|
+
}
|
|
13999
14043
|
function computePresets(scores, defaultFilters, anchorRef, anchorSpec) {
|
|
14000
|
-
const
|
|
14044
|
+
const usesPeptidePreset = isPeptideOrAmplicon(anchorSpec);
|
|
14001
14045
|
const repertoireScore = scores.find((s) => s.getSpec().name === REPERTOIRE_SCORE_COLUMN_NAME);
|
|
14002
14046
|
const hasRepertoireScore = repertoireScore !== void 0;
|
|
14003
14047
|
const isEnrichmentColumn = (name) => name.startsWith("pl7.app/enrichment") || name.startsWith("pl7.app/vdj/enrichment");
|
|
14004
14048
|
const hasEnrichmentScores = scores.some((s) => isEnrichmentColumn(s.getSpec().name));
|
|
14005
|
-
const detectedPreset =
|
|
14049
|
+
const detectedPreset = usesPeptidePreset ? "peptide" : hasRepertoireScore ? "in-vivo" : hasEnrichmentScores ? "in-vitro" : void 0;
|
|
14006
14050
|
const defaultRankingOrder = scores.filter((s) => s.getSpec().valueType !== "String").filter((s) => !hasRepertoireScore || s.getSpec().name !== "pl7.app/vdj/repertoireScore").filter((s) => !hasRepertoireScore || !IN_VIVO_MUTATION_COLUMNS.has(s.getSpec().name)).map((s) => ({
|
|
14007
14051
|
id: `default-rank-${s.id}`,
|
|
14008
14052
|
value: matchToColumnId(s, anchorRef),
|
|
@@ -14471,14 +14515,14 @@ const CLUSTER_ID_SELECTORS = [...CLUSTER_ID_AXIS_NAMES].map((name) => ({ name: e
|
|
|
14471
14515
|
const OWN_PLUMBING_SELECTORS = [{ name: exactMatch("pl7.app/selectionStage") }, { name: exactMatch("pl7.app/lead-selection") }];
|
|
14472
14516
|
/**
|
|
14473
14517
|
* Adapt column recipes to `PColumn`s for the helpers that still take
|
|
14474
|
-
* materialised `PColumn[]` and have no id form (`
|
|
14475
|
-
* `PColumnIdAndSpec`).
|
|
14518
|
+
* materialised `PColumn[]` and have no id form (`getRelatedColumns`,
|
|
14519
|
+
* `createPFrameForGraphs`, `PColumnIdAndSpec`).
|
|
14476
14520
|
*
|
|
14477
14521
|
* Only bare leaves qualify: `PColumn.id` is typed `PObjectId`, which no wrapper
|
|
14478
14522
|
* recipe carries — hence `isDataColumn` rather than `hasReachableData`, which
|
|
14479
|
-
* also admits spec-overrides over a leaf. Deduped by id:
|
|
14480
|
-
*
|
|
14481
|
-
*
|
|
14523
|
+
* also admits spec-overrides over a leaf. Deduped by id: these lists travel as
|
|
14524
|
+
* block columns, and a repeated id aborts the collection scan inside
|
|
14525
|
+
* `getRelatedColumns`.
|
|
14482
14526
|
*/
|
|
14483
14527
|
function toGraphColumns(recipes) {
|
|
14484
14528
|
return dedupColumns(recipes.filter(isDataColumn).map((c) => ({
|
|
@@ -14492,32 +14536,38 @@ function accessorGraphColumns(accessor) {
|
|
|
14492
14536
|
if (!accessor) return void 0;
|
|
14493
14537
|
return toGraphColumns(ColumnsCollection([accessor]).getColumns());
|
|
14494
14538
|
}
|
|
14539
|
+
function umapPoolColumns(ctx) {
|
|
14540
|
+
const clonotypeAxisName = getSpecByRef(getInputAnchorRef(ctx.data))?.axesSpec[1]?.name;
|
|
14541
|
+
if (clonotypeAxisName === void 0) return void 0;
|
|
14542
|
+
const umap = ColumnsCollection(["result_pool"]).filter({ include: {
|
|
14543
|
+
name: "^pl7\\.app/umap[12]$",
|
|
14544
|
+
axes: [{ name: exactMatch(clonotypeAxisName) }]
|
|
14545
|
+
} }).getColumns();
|
|
14546
|
+
if (umap.length === 0) return void 0;
|
|
14547
|
+
return toGraphColumns(umap);
|
|
14548
|
+
}
|
|
14495
14549
|
/**
|
|
14496
|
-
*
|
|
14497
|
-
*
|
|
14550
|
+
* Ids of the columns that join the UMAP projection, discovered once per UMAP
|
|
14551
|
+
* column and unioned, so a second clonotype-space block keyed on its own axis
|
|
14552
|
+
* still contributes.
|
|
14498
14553
|
*
|
|
14499
|
-
*
|
|
14500
|
-
*
|
|
14501
|
-
* name. Omitting `partialAxesMatch` keeps the old exact-axis-set semantics.
|
|
14554
|
+
* Anchors are specs, never ids, so the pool's own copy of a UMAP column cannot
|
|
14555
|
+
* collide with one handed in here.
|
|
14502
14556
|
*/
|
|
14503
|
-
function
|
|
14504
|
-
|
|
14505
|
-
|
|
14506
|
-
|
|
14507
|
-
|
|
14508
|
-
|
|
14509
|
-
|
|
14510
|
-
|
|
14511
|
-
|
|
14512
|
-
|
|
14513
|
-
}).getColumns();
|
|
14514
|
-
if (umap.length === 0) return void 0;
|
|
14515
|
-
const sampledRows = ColumnsCollection([ctx.outputs?.resolve({
|
|
14557
|
+
function umapRelatedIds(umap) {
|
|
14558
|
+
return [...new Set(umap.flatMap((c) => ColumnsCollection().discover({
|
|
14559
|
+
mode: "enrichment",
|
|
14560
|
+
maxHops: 4,
|
|
14561
|
+
anchors: { main: c.spec },
|
|
14562
|
+
exclude: [{ annotations: { [Annotation.HideDataFromUi]: exactMatch("true") } }, { annotations: { [Annotation.HideDataFromGraphs]: exactMatch("true") } }]
|
|
14563
|
+
}).getColumnIds()))];
|
|
14564
|
+
}
|
|
14565
|
+
function sampledRowsGraphColumns(ctx) {
|
|
14566
|
+
return accessorGraphColumns(ctx.outputs?.resolve({
|
|
14516
14567
|
field: "sampledRows",
|
|
14517
14568
|
assertFieldType: "Input",
|
|
14518
14569
|
allowPermanentAbsence: true
|
|
14519
|
-
})
|
|
14520
|
-
return toGraphColumns([...umap, ...sampledRows]);
|
|
14570
|
+
}));
|
|
14521
14571
|
}
|
|
14522
14572
|
const platforma$1 = BlockModelV3.create({
|
|
14523
14573
|
dataModel: blockDataModel,
|
|
@@ -14581,7 +14631,7 @@ const platforma$1 = BlockModelV3.create({
|
|
|
14581
14631
|
}, { retentive: true }).output("modality", (ctx) => {
|
|
14582
14632
|
const spec = getSpecByRef(getInputAnchorRef(ctx.data));
|
|
14583
14633
|
if (!spec) return void 0;
|
|
14584
|
-
return spec
|
|
14634
|
+
return isPeptideOrAmplicon(spec) ? "peptide" : "antibody_tcr";
|
|
14585
14635
|
}, { retentive: true }).output("filterConfig", (ctx) => {
|
|
14586
14636
|
const inputAnchor = getInputAnchorRef(ctx.data);
|
|
14587
14637
|
const result = buildCollection(inputAnchor);
|
|
@@ -14806,13 +14856,14 @@ const platforma$1 = BlockModelV3.create({
|
|
|
14806
14856
|
if (ctx.outputs.getIsReadyOrError() === false) return true;
|
|
14807
14857
|
return false;
|
|
14808
14858
|
}).outputWithStatus("umapPf", (ctx) => {
|
|
14809
|
-
const
|
|
14810
|
-
if (
|
|
14811
|
-
|
|
14859
|
+
const umap = umapPoolColumns(ctx);
|
|
14860
|
+
if (umap === void 0) return void 0;
|
|
14861
|
+
if (umap.some((c) => c.data === void 0)) return void 0;
|
|
14862
|
+
return ctx.createPFrame([...umapRelatedIds(umap), ...umap.map((c) => c.id)]);
|
|
14812
14863
|
}).outputWithStatus("umapPcols", (ctx) => {
|
|
14813
|
-
const
|
|
14814
|
-
if (
|
|
14815
|
-
return
|
|
14864
|
+
const umap = umapPoolColumns(ctx);
|
|
14865
|
+
if (umap === void 0) return void 0;
|
|
14866
|
+
return [...umap, ...sampledRowsGraphColumns(ctx) ?? []].map((c) => ({
|
|
14816
14867
|
columnId: c.id,
|
|
14817
14868
|
spec: c.spec
|
|
14818
14869
|
}));
|
|
@@ -14864,9 +14915,9 @@ const platforma$1 = BlockModelV3.create({
|
|
|
14864
14915
|
if (numbered === 0) return "Kabat numbering could not be applied to any clonotype. The framework regions may be too divergent from known germline sequences. Kabat sequence columns will be empty.";
|
|
14865
14916
|
return `Kabat numbering was applied to ${numbered.toLocaleString()} clonotype${numbered === 1 ? "" : "s"}. Clonotypes that could not be numbered will have empty Kabat sequence columns.`;
|
|
14866
14917
|
}).output("isRunning", (ctx) => ctx.outputs?.getIsReadyOrError() === false).title(() => "Lead Selection").subtitle((ctx) => ctx.data.customBlockLabel || ctx.data.defaultBlockLabel).sections((ctx) => {
|
|
14867
|
-
const
|
|
14868
|
-
const
|
|
14869
|
-
const spaceLabel =
|
|
14918
|
+
const anchorSpec = getSpecByRef(getInputAnchorRef(ctx.data));
|
|
14919
|
+
const source = anchorSpec !== void 0 ? recordSource(anchorSpec) : "unknown";
|
|
14920
|
+
const spaceLabel = source === "amplicon" ? "Variant Space" : source === "peptide" ? "Peptide Space" : "Clonotype Space";
|
|
14870
14921
|
const sections = [
|
|
14871
14922
|
{
|
|
14872
14923
|
type: "link",
|
|
@@ -14884,7 +14935,7 @@ const platforma$1 = BlockModelV3.create({
|
|
|
14884
14935
|
label: "Selection Plot"
|
|
14885
14936
|
}
|
|
14886
14937
|
];
|
|
14887
|
-
if (
|
|
14938
|
+
if (anchorSpec !== void 0 && hasGeneCalls(anchorSpec)) sections.push({
|
|
14888
14939
|
type: "link",
|
|
14889
14940
|
href: "/spectratype",
|
|
14890
14941
|
label: "CDR3 V Spectratype"
|