@jbrowse/bandage-core 0.1.4 → 0.1.5
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/dist/index.js +92 -3
- package/dist/types/index.d.ts +2 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -269,12 +269,12 @@ function parseGFA(file) {
|
|
|
269
269
|
});
|
|
270
270
|
}
|
|
271
271
|
} else if (line.startsWith("W")) {
|
|
272
|
-
const [, sample, hap,
|
|
273
|
-
if (sample && hap &&
|
|
272
|
+
const [, sample, hap, contig2, start, end, body, ...rest] = line.split(" ");
|
|
273
|
+
if (sample && hap && contig2 && start && end && body) {
|
|
274
274
|
graph.walks.push({
|
|
275
275
|
sample,
|
|
276
276
|
haplotype: +hap,
|
|
277
|
-
contig,
|
|
277
|
+
contig: contig2,
|
|
278
278
|
start: start === "*" ? -1 : +start,
|
|
279
279
|
end: end === "*" ? -1 : +end,
|
|
280
280
|
segments: parseWalkBody(body),
|
|
@@ -660,6 +660,14 @@ function splitRuns(positions, runs, weightOf) {
|
|
|
660
660
|
}
|
|
661
661
|
return out;
|
|
662
662
|
}
|
|
663
|
+
function polylineSlice(line, from, to) {
|
|
664
|
+
if (line.length === 0) {
|
|
665
|
+
return [];
|
|
666
|
+
}
|
|
667
|
+
const arc = arcPrefix(line);
|
|
668
|
+
const total = arc.at(-1);
|
|
669
|
+
return slice(line, arc, from * total, to * total);
|
|
670
|
+
}
|
|
663
671
|
function polylineMidpoint(line) {
|
|
664
672
|
const arc = arcPrefix(line);
|
|
665
673
|
return pointAt(line, arc, arc.at(-1) / 2);
|
|
@@ -5202,6 +5210,86 @@ function layoutLabels(m) {
|
|
|
5202
5210
|
};
|
|
5203
5211
|
}
|
|
5204
5212
|
|
|
5213
|
+
// src/genes/genePins.ts
|
|
5214
|
+
function contig(name) {
|
|
5215
|
+
return name.split("#").at(-1);
|
|
5216
|
+
}
|
|
5217
|
+
function genePins(graph, genes, positions) {
|
|
5218
|
+
const byContig = /* @__PURE__ */ new Map();
|
|
5219
|
+
const contigOf = /* @__PURE__ */ new Map();
|
|
5220
|
+
for (const node of graph.nodes) {
|
|
5221
|
+
if (isBackbone(node) && positions[node.id]?.length) {
|
|
5222
|
+
const { refName } = node.stable;
|
|
5223
|
+
const name = contigOf.get(refName) ?? contigOf.set(refName, contig(refName)).get(refName);
|
|
5224
|
+
const entry = byContig.get(name) ?? byContig.set(name, { nodes: [], reach: 0 }).get(name);
|
|
5225
|
+
entry.nodes.push(node);
|
|
5226
|
+
entry.reach = Math.max(entry.reach, node.length);
|
|
5227
|
+
}
|
|
5228
|
+
}
|
|
5229
|
+
for (const { nodes } of byContig.values()) {
|
|
5230
|
+
nodes.sort((a, b) => a.stable.start - b.stable.start);
|
|
5231
|
+
}
|
|
5232
|
+
const pins = [];
|
|
5233
|
+
for (const gene of genes) {
|
|
5234
|
+
const backbone = byContig.get(contig(gene.refName));
|
|
5235
|
+
if (!backbone) {
|
|
5236
|
+
continue;
|
|
5237
|
+
}
|
|
5238
|
+
const parts = [];
|
|
5239
|
+
let at;
|
|
5240
|
+
let atDistance = Infinity;
|
|
5241
|
+
let covered = 0;
|
|
5242
|
+
const mid = (gene.start + gene.end) / 2;
|
|
5243
|
+
const { nodes, reach } = backbone;
|
|
5244
|
+
for (let i = firstNodeAtOrAfter(nodes, gene.start - reach); i < nodes.length && nodes[i].stable.start < gene.end; i++) {
|
|
5245
|
+
const node = nodes[i];
|
|
5246
|
+
const nodeStart = node.stable.start;
|
|
5247
|
+
const nodeEnd = nodeStart + node.length;
|
|
5248
|
+
if (nodeEnd <= gene.start) {
|
|
5249
|
+
continue;
|
|
5250
|
+
}
|
|
5251
|
+
const line = positions[node.id];
|
|
5252
|
+
covered += Math.min(nodeEnd, gene.end) - Math.max(nodeStart, gene.start);
|
|
5253
|
+
for (const exon of gene.exons) {
|
|
5254
|
+
const a = Math.max(exon.start, nodeStart);
|
|
5255
|
+
const b = Math.min(exon.end, nodeEnd);
|
|
5256
|
+
if (b <= a) {
|
|
5257
|
+
continue;
|
|
5258
|
+
}
|
|
5259
|
+
const stretch = polylineSlice(
|
|
5260
|
+
line,
|
|
5261
|
+
(a - nodeStart) / node.length,
|
|
5262
|
+
(b - nodeStart) / node.length
|
|
5263
|
+
);
|
|
5264
|
+
if (stretch.length === 1) {
|
|
5265
|
+
stretch.push({ ...stretch[0] });
|
|
5266
|
+
}
|
|
5267
|
+
parts.push(svgPath(stretch));
|
|
5268
|
+
}
|
|
5269
|
+
const pinBp = Math.min(Math.max(mid, nodeStart), nodeEnd);
|
|
5270
|
+
const distance = Math.abs(pinBp - mid);
|
|
5271
|
+
if (distance < atDistance) {
|
|
5272
|
+
atDistance = distance;
|
|
5273
|
+
const [p] = polylineSlice(
|
|
5274
|
+
line,
|
|
5275
|
+
(pinBp - nodeStart) / node.length,
|
|
5276
|
+
(pinBp - nodeStart) / node.length
|
|
5277
|
+
);
|
|
5278
|
+
at = p;
|
|
5279
|
+
}
|
|
5280
|
+
}
|
|
5281
|
+
if (at) {
|
|
5282
|
+
pins.push({
|
|
5283
|
+
gene,
|
|
5284
|
+
exons: parts.join(""),
|
|
5285
|
+
at,
|
|
5286
|
+
covered: covered / (gene.end - gene.start)
|
|
5287
|
+
});
|
|
5288
|
+
}
|
|
5289
|
+
}
|
|
5290
|
+
return pins;
|
|
5291
|
+
}
|
|
5292
|
+
|
|
5205
5293
|
// src/gbzWindow.ts
|
|
5206
5294
|
var NoReferenceSampleError = class extends Error {
|
|
5207
5295
|
constructor(anchor, referenceSamples) {
|
|
@@ -5374,6 +5462,7 @@ export {
|
|
|
5374
5462
|
fitTransform,
|
|
5375
5463
|
forceLayout,
|
|
5376
5464
|
formatBp2 as formatBp,
|
|
5465
|
+
genePins,
|
|
5377
5466
|
getDpr,
|
|
5378
5467
|
haplotypeWanted,
|
|
5379
5468
|
layoutExtent,
|
package/dist/types/index.d.ts
CHANGED
|
@@ -39,6 +39,8 @@ export { ROW_HEIGHT_PX } from './layout/rowSpacing.js';
|
|
|
39
39
|
export { HALO_FACTOR, LEGEND_INSET_PX, layoutLabels } from './labelLayout.js';
|
|
40
40
|
export type { BubbleGlyph, LabelLayout, LabelLayoutSource } from './labelLayout.js';
|
|
41
41
|
export { formatBp } from './graphLabels.js';
|
|
42
|
+
export { genePins } from './genes/genePins.js';
|
|
43
|
+
export type { GeneModel, GenePin } from './genes/genePins.js';
|
|
42
44
|
export { LABEL_CHAR_PX, LABEL_PAD, LABEL_PX } from './overlayLabels.js';
|
|
43
45
|
export type { Graph, GraphEdge, GraphNode, LayoutResult, NodeSegment, } from './types.js';
|
|
44
46
|
export { cutWindowGFA, haplotypeWanted, referencePathQuery, referenceSamplesOf, resolveReferenceSample, } from './gbzWindow.js';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jbrowse/bandage-core",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.5",
|
|
4
4
|
"description": "Pangenome graph layout and drawing with no host: GFA in, the Bandage force-directed engine and reference-anchored layouts, a Canvas2D renderer, hit testing and labels out",
|
|
5
5
|
"license": "GPL-3.0-or-later",
|
|
6
6
|
"repository": {
|